Borislav Hadzhiev
Tue Mar 01 2022·3 min read
Photo by Lê Tân
The "Property does not exist on type '{}'" error occurs when we try to access or set a property that is not contained in the object's type. To solve the error, type the object properties explicitly or use a type with variable key names.
Here is an example of how the error occurs:
const obj = {}; // ⛔️ Error: Property 'name' does not // exist on type '{}'.ts(2339) obj.name = 'Tom';
We didn't explicitly type the obj
variable and declared it to an empty object,
so we aren't able to assign or access properties that don't exist on the
object's type.
To solve the error, type the object explicitly to include any of the properties you intend to access.
// ✅ When you know property names ahead of time type Employee = { id?: number; name?: string; }; const obj: Employee = {}; obj.id = 1; obj.name = 'Alice'; // ✅ When you don't know ALL property names ahead of time type Employee2 = { [key: string]: any; // 👈️ variable key name: string; }; const obj2: Employee2 = { name: 'James', }; obj2.salary = 100;
The first example shows how to type an object when you know its property names and the types of the values ahead of time.
Because we need to declare the object as empty, we marked the properties as optional by using a question mark.
id
and name
properties can be assigned later on.The important thing here is - the properties exist on the object type, so we
won't get the "Property does not exist on type {}
" error when accessing them.
In some cases, you won't know the names of all of the object's keys or the shape of the values ahead of time.
type Employee2 = { [key: string]: any; // 👈️ variable key name: string; }; const obj2: Employee2 = { name: 'James', }; obj2.salary = 100;
The {[key: string]: any}
syntax is called an
index signature
and is used when you don't know the names of the object's keys or the shape of
the values ahead of time.
The syntax basically means that when the object is indexed with a string key, it
will return a value of any
type.
We set the name
property to string
in the Employee2
type, so the type
checker would throw an error if the property is not provided or is set to a
value of a different type.
If you don't know the names of all of the object's keys, but know the shape of the values, you can use a more specific index signature for better type safety.
type Employee2 = { [key: string]: string | number; name: string; id: number; }; const obj2: Employee2 = { id: 1, name: 'James', }; obj2.department = 'accounting'; obj2.salary = 100;
The index signature in the example above means that when the object is indexed
with a string key, it will return a value that has a string
or number
type.
The string | number
syntax is called a
union type
in TypeScript.
name
and id
properties are strings and they return different types.In other words, you can't specify that when the object is indexed with a string
key, it returns a value of type string
and add another string key to the
interface that has a value of type number
.
type Employee2 = { [key: string]: string; name: string; // ⛔️ Error: Property 'id' of type 'number' is // not assignable to 'string' index type 'string'.ts(2411) id: number; };
The example above shows that the type checker throws an error if we specify that
when indexed with a string key, the object returns a value of type string
, and
try to add another string key that has a value of number
.
To solve the "Property does not exist on type '{}'" error, make sure to only access properties on the object that exist on the object's type. If you try to access a property that does not exist on the object's type, the error is thrown.