# Table of Contents
- Property does not exist on type '{}' in TypeScript
- Don't use the Object type when typing objects
- Property does not exist on type Union in TypeScript
- Property 'status' does not exist on type 'Error' in TS
# Property does not exist on type '{}' in TypeScript
The "Property does not exist on type '{}'" error occurs when we try to accessor 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 withvariable key names.
Here is an example of how the error occurs:
index.ts
Copied!
const obj = {};// ⛔️ Error: Property 'name' does not exist on type '{}'.ts(2339)obj.name = 'Bobby Hadz';
You might also get the error if you use the Object
type.
index.ts
Copied!
const obj: Object = {};// ⛔️ Property 'name' does not exist on type 'Object'.obj.name = 'Bobby Hadz';
We didn't explicitly type the obj
variable and initialized it to an emptyobject, so we aren't able to assign or access properties that don't exist on theobject's type.
# Explicitly type the object to solve the error
To solve the error,type the object explicitly and specifyall of the properties you intend to access.
index.ts
Copied!
// ✅ When you know property names ahead of timetype Employee = { id?: number; name?: string;};const obj: Employee = {};obj.id = 1;obj.name = 'Bobby Hadz';
The code for this article is available on GitHub
If you don't know all of the property names ahead of time, use anindex signature.
index.ts
Copied!
// ✅ When you don't know ALL property names ahead of timetype Employee = { [key: string]: any; // 👈️ variable key name: string;};const obj: Employee = { name: 'Bobby Hadz',};obj.salary = 100;
The first example shows how to type an object when you know its property namesand the type of its values ahead of time.
We need todeclare the object as empty, so wemarked the properties asoptionalby using a question mark.
index.ts
Copied!
// ✅ When you know property names ahead of timetype Employee = { id?: number; name?: string;};const obj: Employee = {};obj.id = 1;obj.name = 'Bobby Hadz';
Now the object can be initialized as empty and the id
and name
properties can be assigned later on.
The properties exist on the object's type, so we won't get the "Property doesnot exist on type 'Object'" error when accessing them.
You can alsomake all of an object's properties optionalby using the Partial
type.
# When you don't know the names of all of the object's properties
In some cases, you won't know the names of all of the object's keys or the shapeof the values ahead of time.
index.ts
Copied!
type Employee = { [key: string]: any; // 👈️ variable key name: string;};const obj: Employee = { name: 'Bobby Hadz',};obj.salary = 100;
The code for this article is available on GitHub
The{[key: string]: any}syntax is called anindex signatureand is used when you don't know the names of the object's keys or the shape ofthe values ahead of time.
The syntax means that when the object is indexed with a string key, it willreturn a value of any
type.
If you know any of the names of the properties ahead of time, you can specify them to get better type safety.
We set the name
property to string
in the Employee
type, so the typechecker would throw an error if the property is not provided or is set to avalue of a different type.
# If you don't know the names of all keys but know the shape of the values
If you don't know the names of all of the object's keys but know the shape ofthe values, you can use a more specific index signature for better type safety.
index.ts
Copied!
type Employee = { [key: string]: string | number; name: string; id: number;};const obj: Employee = { id: 1, name: 'Bobby Hadz',};obj.department = 'accounting';obj.salary = 100;
The code for this article is available on GitHub
The index signature means that when the object is indexed with a string key, itwill return a value that has a string
or number
type.
The string | number
syntax is called aunion type in TypeScript.
We had to use a union type because the 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 stringkey, it returns a value of type string
and then add another string key to theinterface that has a value oftype number
.
index.ts
Copied!
type Employee = { [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 shows that the type checker throws an error if we specify that whenindexed with a string key, the object returns a value of type string
and tryto add another string key that has a value of type number
.
# Use the any
type if you want to turn off type-checking
If you just want to turn off type checking and be able to add any property tothe object, set its type to any
.
index.ts
Copied!
const obj: any = {};obj.name = 'Bobby Hadz';obj.age = 30;console.log(obj); // 👉️ { name: 'Bobby Hadz', age: 30 }
The code for this article is available on GitHub
The any
type effectivelyturns off type checking and enables usto add any property to the object.
However, when we use this approach we don't take advantage of the benefits thatTypeScript provides.
# Don't use the Object
type when typing objects
The following code sample raises the same error when we try to access a propertythat doesn't exist on the object's type.
index.ts
Copied!
const obj: Object = { name: 'Bobby Hadz', age: 30,};// ⛔️ Error: Property 'country' does not exist on type 'Object'.ts(2339)obj.country = 'Chile';
We typed the obj
variable as Object
and tried to access the country
property on the object.
However, the country
property does not exist on the Object
type, so the type checker throws an error.
This is only 1 of the issues in the code sample.
The Object
type should never be used to type a value in TypeScript.
The Object
type means "any non-nullish value". In other words, it means anyvalue that is not null
or undefined
.
# Property does not exist on type Union in TypeScript
The "property does not exist on type union" error occurs when we try to accessa property that is not present on every object in the union type.
To solve the error, use a type guard to ensure the property exists on theobject before accessing it.
Here is an example of how the error occurs.
index.ts
Copied!
type Person = { age: number;};type Employee = { salary: number;};function getProperty(obj: Person | Employee): number { // ⛔️ Error: Property 'age' does not exist on type 'Person | Employee'. if (obj.age) { return obj.age; } return obj.salary;}
The age
property doesn't exist on all of the types in theunion,so we aren't able to access it directly.
# Use a type guard to solve the error
Instead, we have to use a type guardto check if the property exists in the object before accessing it.
index.ts
Copied!
type Person = { age: number;};type Employee = { salary: number;};function getProperty(obj: Person | Employee): number { if ('age' in obj) { return obj.age; } return obj.salary;}
The code for this article is available on GitHub
We used thein operator,which is a type guard in TypeScript.
The in
operator returns true
if the specified property is in the object orits prototype chain.
index.ts
Copied!
const obj = { a: 'hello',};console.log('a' in obj); // 👉️ trueconsole.log('b' in obj); // 👉️ false
This way, TypeScript can infer the type of the object in the if
block andafter the if
block.
index.ts
Copied!
type Person = { age: number;};type Employee = { salary: number;};function getProperty(obj: Person | Employee): number { if ('age' in obj) { // 👇️ now `obj` is type `Person` return obj.age; } // 👇️ now `obj` is type `Employee` return obj.salary;}
If the age
property is contained in the passed-in object, we can safely use the age
property and TypeScript is able to infer the type of obj
to be Person
.
If the if
block doesn't run, then the age
property isn't in the passed-inobject and TypeScript infers the type of obj
to be Employee
.
If you need to check if a string is in a union type, click on thefollowing article.
# Property 'status' does not exist on type 'Error' in TS
The error "Property 'status' does not exist on type 'Error'" occurs becausethe status
property is not available on the Error
interface.
To solve the error, add the specific property to the Error
interface orcreate a custom class that extends from Error
.
Here is an example of how the error occurs.
index.ts
Copied!
const err = new Error('Something went wrong');// ⛔️ Property 'status' does not exist on type 'Error'.ts(2339)err.status = 500;// ⛔️ Property 'code' does not exist on type 'Error'.ts(2339)console.log(err.code);
The reason we got the errors in the example above is that the status
andcode
properties don't exist on the Error
interface.
By default, the Error
interface has the following properties:
index.ts
Copied!
interface Error { name: string; message: string; stack?: string;}
To get around this, we can extend the Error
class.
index.ts
Copied!
export class CustomError extends Error { status: number = 200; code: number = 200; constructor(message: string) { super(message); // 👇️ because we are extending a built-in class Object.setPrototypeOf(this, CustomError.prototype); }}const err = new CustomError('Something went wrong');err.status = 500;console.log(err.status);err.code = 500;console.log(err.code);
The code for this article is available on GitHub
The CustomError
class extends from the built-in Error
class and adds thestatus
and code
properties.
If you want to read more on how to extend from the Error
class in TypeScript,check out this article.
# Additional Resources
You can learn more about the related topics by checking out the followingtutorials:
- Create a custom Class that extends from Error in TypeScript
- Property 'X' does not exist on type Request in TypeScript
- Property does not exist on type Window in TypeScript
- Property does not exist on type String in TypeScript [Fixed]
- Property 'flatMap', 'flat' does not exist on type in TS