Last updated: Feb 27, 2024
Reading time·4 min
The "Object literal may only specify known properties" error occurs when a property in an object literal doesn't exist in the object's type.
To solve the error, make sure to type all of the object's properties and fix spelling errors in property names if you have any.
Here is an example of how the error occurs.
type Employee = { id: number; }; // ⛔️ Object literal may only specify known // properties, and 'name' does not exist in type 'Employee'. const emp: Employee = { id: 1, name: 'Bobby hadz' };
The Employee
type only has an id
property, so when we try to add a name
property to an object of type Employee
, the error occurs.
To solve this, make sure to type all of the properties the object literal will have (if you know the property names ahead of time).
type Employee = { id: number; name: string; }; const emp: Employee = { id: 1, name: 'Bobby Hadz' };
We added the name
property to the Employee
type, so the type checker doesn't
throw the error anymore.
Sometimes you don't know the names of all of the properties in the object ahead of time.
In this case, use an index signature.
type Employee = { id: number; [key: string]: any; }; const emp: Employee = { id: 1, name: 'Bobby Hadz', department: 'accounting', };
The {[key: string]: any}
syntax is called an index signature and is used when
we don't know all of the object's property names and the shape of the values
ahead of time.
string
key, it will return a value of any
type (very broad).Notice that we are still able to specify the id
property, setting it to
number
because we know all objects of type Employee
will have it.
You should always explicitly specify the properties you know about when using this approach because it provides better type checking.
If you don't know all of the object's property names but know the shape of the values, you can use a stricter index signature for better type safety.
type Employee = { id: number; [key: string]: string | number; }; const emp: Employee = { id: 1, name: 'Bobby Hadz', department: 'accounting', salary: 100, };
The {[key: string]: string | number}
syntax means that when the object is
indexed with a string key, it will return a value that is of type string
or
number
.
The string | number
syntax is called a
union type in TypeScript.
Now we can add any properties to the object that have a value of type string
or number
which is much better for type safety than specifying a value of type
any
.
Note that when using this approach, you aren't able to add string keys that have
a value of type other than string | number
.
type Employee = { id: number; [key: string]: string | number; // ⛔️ Error: Property 'years' of type 'number[]' // is not assignable to 'string' index type 'string | number'. years: number[]; };
With our index signature of [key: string]: string | number
, we told TypeScript
that when a string key is accessed, it will return a value that is a string
or
a number
, so we can't add another string key that has a type of number[]
.
To get around this, you have to add number[]
to the union type.
type Employee = { id: number; [key: string]: string | number | number[]; years: number[]; }; const emp: Employee = { id: 1, name: 'Bobby Hadz', department: 'accounting', salary: 100, years: [2022, 2023], };
If you are unsure what properties the object will contain, but generally know that it will be one of X specific types, use a union type.
class Bird { fly() { console.log('bird flies'); } } class Fish { swim() { console.log('fish swims'); } } let obj: Bird | Fish; // 👇️ (your condition here) if (Math.random() > 0.5) { obj = new Bird(); } else { obj = new Fish(); } console.log(obj); // 👉️ Bird {}
The obj
variable stores an object of type Bird
or Fish
.
If the condition is met, we assign a Bird
instance to the object, otherwise,
we assign a Fish
instance to the object.
We can assign either value to the object because we used a union type.
I've also written an article on how to get an object's key by value in TS.
You can learn more about the related topics by checking out the following tutorials: