Differences between Typescript compilation: Using dot notation vs square brackets when accessing non-existent properties

Imagine having the given class and code snippet:

class myClass{ 
   x: number;
}
const obj = new myClass();
obj.y = 7; // produces a compile error. Property 'y' does not exist on type myClass.
obj['y'] = 7; // compiles without any issues.

What sets apart using dot notation from utilizing square brackets? Are they essentially interchangeable?

Answer №1

When using square brackets like o['b'], the o object is treated as an any type in Typescript, which means no type checks will be applied.

To receive warnings, you can set the noImplicitAny: true attribute in your tsconfig.json file. This will result in an error stating

Element implicitly has an 'any' type because type 'MyClass' has no index signature.
for o['b']. To work around this issue, you must explicitly declare that o should be treated as an any type like so: (o as any)['b'].

An exception to this rule is if you define an attribute in MyClass that already exists. For example:

export class MyClass{
   a: number;
   "Weirdly-Named-Attribute": number;
}
const o = new MyClass();
o["a"] = 4; // compiles
o["Weirdly-Named-Attribute"] = 5; // compiles
o["b"] = 6; // Gives `Element implicitly has an 'any' type` error if `noImplicityAny` is enabled in tsconfig.

Answer №2

o.b is interpreted by the compiler as specifying: "I am initializing this attribute (b in this case) of the MyClass class." This results in a compilation error. On the other hand, o['b'] creates a new attribute b within the instance o belonging to the type MyClass, allowing it to compile successfully.

Essentially, the distinction between using a dot and square brackets lies in the fact that the dot attempts to access the desired property of the instance, while square brackets will either assign a value to an existing property within the class or create the attribute and assign the value if it does not already exist.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

reinstate dummy of external class method in ts-jest

Problem I am encountering an issue while trying to mock a function that is imported from another class and called within the main class. Although I can successfully mock the function and return the specified values, I am unable to revert the mocked functi ...

Having trouble with Angular 4 data display? See how to fix a simple example that's

I can't seem to display my data correctly in Angular. When I try, all I get are empty bullet points and an error message that says "Cannot read property of 0 undefined." Even though the code appears to be correct, it's not functioning as expected ...

Confounding Typescript Type Bindings

I am facing an issue with my Typescript component that uses react-jss and the classes object for styling. The error message I'm getting is: Binding element 'classes' implicitly has an 'any' type., and I'm struggling to find a ...

Solving the issue of refreshing HTML Canvas drawings in Vue3 using the Composition API

In my typescript code base, I have successfully created a Sudoku board by directly manipulating the DOM and utilizing an HTML Canvas element with its API. Now, I am looking to elevate my project to a full website and integrate what I have into a Vue3 proj ...

Utilizing an external TypeScript class without the need for importing it

Let's consider a scenario where we have a class named Constant. The requirement is to make this class accessible globally without the need for importing, is there a way to achieve this? In the constant.ts file: class Constant { public stati ...

Display a child element depending on a certain condition

Looking to implement a switch higher-order component (HOC) for conditional rendering that mimics a switch statement in ReactTS. <Switch> <Case condition={cond1}> Hello </Case> <Case condition={cond2}> Wor ...

Testing Material-UI's autocomplete with React Testing Library: a step-by-step guide

I am currently using the material-ui autocomplete component and attempting to test it with react-testing-library. Component: /* eslint-disable no-use-before-define */ import TextField from '@material-ui/core/TextField'; import Autocomplete from ...

The outcome from using Array.reduce may not always match the expected result

After discovering an unexpected behavior in Typescript's type-inference, I suspect there may be a bug. Imagine having a list of the MyItem interface. interface MyItem { id?: string; value: string; } const myItemList: MyItem[] = []; It's ...

Managing time in an Angular application using Typescript

I am facing an issue with formatting the time obtained from an API in my FormArray. The time is received in the format: 14.21.00 My goal is to convert this time to the following format: 2:21 PM I have attempted to format it using Angular's DatePip ...

calculate the difference between two dates and then add this difference to a new date

Utilizing TypeScript for date calculations. Example: Initial Date 1: "10/06/2021 10:10:05" Initial Date 2: "08/06/2021 11:10:05" Calculate the difference between the two dates, including date/month/year/hour/min/sec/milliseconds. Ensure compatibility wi ...

Error message: "Encountered a template parsing error stating that the element 'ngb-carousel' is not recognized."

Initially, I created a fresh project using the Angular CLI by running this command: ng new my-project Next, I followed the instructions in the angular-cli readme to install Bootstrap 4. After that, I installed NG Bootstrap. Then, I generated a new comp ...

Chaining Assignments in TypeScript

let a: { m?: string }; let b = a = {}; b.m = ''; // Property 'm' does not exist on type '{}'. let a: { m?: string } = {}; let b = a; b.m = ''; // It's OK Link to TypeScript Playground What occurs ...

Using Angular 2, you can pass an object as a parameter to a function

Is there a way to pass an object as a parameter in the DOM on this forum? Within my HTML code, I have the following: <div class="list-items"> <ul> <li *ngFor="let i of item"> <span (click)="onAdd({{newUser.us ...

Issues encountered with node_modules during production build

I am facing multiple errors when attempting to build the application for production. Strangely, these errors do not appear when running ng build. The errors only pop up when trying to run ng build --prod. Is there a solution to resolve this issue? Apprec ...

Creating a gradient background with the makeStyles function

Why is it that the background: 'linear-gradient(to right, blue.200, blue.700)' doesn't work within makeStyles? I just want to add a gradient background to the entire area. Do you think <Container className={classes.root}> should be rep ...

Personalizing the predefined title bar outline of the input text field

The outline color of the title in the input textbox appears differently in Google Chrome, and the bottom border line looks different as well. <input type="text" title="Please fill out this field."> https://i.stack.imgur.com/iJwPp.png To address th ...

Encountering errors while adding Storybook to a TypeScript-react project with existing stories

I recently added storybook to my TypeScript React project, but I encountered an error when running yarn storybook. The issue seems to be related to the "as" keyword in the generated code. -- Error message Parsing error: Missing semicolon 10 | back ...

Guide to Setting Up "Remember Me" Login for Users in Angular

I am having trouble setting the 'Remember Me' option on my Login page. I tried using localstorage session but it seems like something is missing in the service file that's causing it not to respond properly. I attempted to follow a guide on ...

What sets apart exporting a component from importing its module in another module?

When working with Angular, consider having both module A and module B. If I intend to utilize "A-component" within components of module B, what is the distinction between importing module A in Module B compared to including the "A-component" in the exports ...

Having trouble adding custom props to MUI-Material ListItemButtonProps? Facing a TypeScript error?

This particular task should be relatively straightforward. I am seeking a custom component that inherits all props from ListItemButtonProps, while also adding an extra state prop: type SidebarListItemButtonProps = ListItemButtonProps & { state: Sideb ...