Introduction
Contemplate the next instance:
const group = {} group.identify = "Logrocket"
This seemingly innocent piece of code throws a TypeScript error on dynamically assigning identify
to the group
object.
See this instance in the TypeScript Playground.
The supply of confusion, which is probably rightly justified if you happen to’re a TypeScript newbie, is: how might one thing that appears so easy be such an issue in TypeScript?
The TL;DR of all of it is that, if you happen to can’t outline the variable kind at declaration time, you need to use the File
utility kind or an object index signature to unravel this. However on this submit, we’ll undergo the issue itself and work towards an answer that ought to work typically.
Soar forward:
Understanding the issue with dynamically assigning properties to things
Usually talking, TypeScript determines the kind of a variable when it’s declared, and this decided kind doesn’t change, i.e., it stays the identical all by way of your utility.
There are exceptions to this rule, reminiscent of when contemplating kind narrowing or working with the any
kind, however this can be a normal rule to recollect in any other case.
Within the earlier instance, the group
object is said as follows:
const group = {}
There isn’t a express kind assigned to the group
variable, so TypeScript infers a kind of group
primarily based on the declaration to be {}
, i.e., the literal empty object.
For instance, if you happen to add a kind alias, you’ll be able to discover the kind of group
:
kind Org = typeof group
See this in the TypeScript Playground.
Whenever you then attempt to reference the identify
prop on this empty object literal:
group.identify = ...
TypeScript yells.
Property ‘identify’ doesn’t exist on kind ‘
{}
‘
Whenever you perceive the problem, the error does appear acceptable.
Let’s repair this.
Resolving the issue
There are quite a few methods you’ll be able to resolve the TypeScript error right here. Let’s contemplate these:
Extra nice articles from LogRocket:
Answer 1: Explicitly kind the thing at declaration time
That is the best resolution to motive by way of. On the time you declare the thing, go forward and sort it. Moreover, assign it all of the related values.
kind Org = { identify: string } const group: Org = { identify: "Logrocket" }
See this in the TypeScript Playground.
This eliminates any surprises. You’re clearly stating what this object kind is and rightly declaring all related properties while you create the thing.
Nonetheless, this isn’t all the time possible if the thing properties should be added dynamically, which is why we’re all right here.
Answer 2: Use an object index signature
Often, the properties of the thing really must be added at a time after they’ve been declared. On this case, you need to use the thing index signature, as follows:
kind Org = {[key: string] : string} const group: Org = {} group.identify = "Logrocket"
See this in the TypeScript Playground.
On the time the group
variable is said, you’ll be able to go forward and explicitly kind it to the next {[key: string] : string}
.
To elucidate the syntax additional, you could be used to object sorts having mounted property sorts:
kind obj = { identify: string }
Nonetheless, you too can substitute identify
for a “variable kind”.
For instance, if you wish to outline any string property on obj
:
kind obj = { [key: string]: string }
Notice that the syntax is much like the way you’d use a variable object property in commonplace JavaScript:
const variable = "identify" const obj = { [variable]: "Freecodecamp" }
The TypeScript equal is named an object index signature. Furthermore, observe that you could possibly kind key
with different primitives:
// quantity kind Org = {[key: number] : string} // string kind Org = {[key: string] : string} //boolean kind Org = {[key: boolean] : string}
Answer 3: Use the File
utility kind
The File
utility kind permits you to constrict an object kind whose properties are Keys
and property values are Kind
. It has the next signature: File<Keys, Kind>
.
In our instance, Keys
represents string
and Kind
, string
as nicely. The answer right here is sort of concise as proven beneath:
kind Org = File<string, string> const group: Org = {} group.identify = "Logrocket"
As a substitute of utilizing a kind alias, you too can inline the kind:
const group: File<string, string> = {}
See this in the TypeScript Playground.
Conclusion
Other than primitives, the commonest sorts you’ll should cope with are seemingly object sorts.
In circumstances the place you must construct an object dynamically, make the most of the File
utility kind or use the thing index signature to outline the allowed properties on the thing.
For those who’d prefer to learn extra on this topic, be at liberty to take a look at my cheatsheet on the seven most-asked TypeScript questions on Stack Overflow, or tweet me any questions. Cheers!
LogRocket proactively surfaces and diagnoses crucial points in your TypeScript apps
Hundreds of engineering and product groups use LogRocket to cut back the time it takes to know the basis reason behind technical and value points of their TypeScript apps. With LogRocket, you may spend much less time on back-and-forth conversations with clients and take away the countless troubleshooting course of. LogRocket permits you to spend extra time constructing new issues and fewer time fixing bugs.
Proactively repair your TypeScript apps — strive LogRocket at this time.