Last updated: Feb 28, 2024
Reading timeยท4 min
The error "Type 'X' has no properties with type 'Y'" occurs when we try to assign anything to a weak type when there's no overlap in properties.
To solve the error, declare any overlapping properties if they exist or use a type assertion.
Here is an example of how the error occurs.
// ๐๏ธ Weak type (all properties optional) interface Employee { id?: number; salary?: number; } function getEmployee(emp: Employee) { return emp; } // ๐๏ธ No overlap in properties with Employee const emp = { name: 'Bobby Hadz', }; // โ๏ธ Error: Type '{ name: string; }' has no // properties in common with type 'Employee'.ts(2559) getEmployee(emp);
The Employee
type is a
weak type,
because all of its properties are optional.
The question mark is used to mark the type's properties as
optional
and means that the property can either be of the specified type or be
undefined
.
The Employee
type is a weak type because you could create an
empty object that conforms to the type.
interface Employee { id?: number; salary?: number; } // โ This is ok const e: Employee = {};
The cause of the error is that we pass the emp
object to a function that
expects an object of type Employee
and the emp
variable
has no overlap
with the Employee
type.
One way to solve the error is to use a type assertion.
interface Employee { id?: number; salary?: number; } function getEmployee(emp: Employee) { return emp; } const emp = { name: 'Bobby Hadz', }; // ๐๏ธ {name: 'Bobby Hadz'} getEmployee(emp as Employee); // ๐๏ธ use type assertion
emp
variable is definitely of type Employee
.An alternative solution is to make sure there is an overlap between the
Employee
type and the emp
object.
For example, we can add the name
property to the Employee
type.
interface Employee { id?: number; salary?: number; name?: string; // ๐๏ธ added name } function getEmployee(emp: Employee) { return emp; } const emp = { name: 'Bobby Hadz', }; // ๐๏ธ {name: 'Bobby Hadz'} console.log(getEmployee(emp));
We added the name
property to the Employee
type, so now there is an overlap
between the type and the emp
object.
If you aren't able to alter the type, you can add an overlapping property to the object.
interface Employee { id?: number; salary?: number; } function getEmployee(emp: Employee) { return emp; } const emp = { name: 'Bobby Hadz', id: 0, // ๐๏ธ added id property }; // ๐๏ธ {name: 'Bobby Hadz'} console.log(getEmployee(emp));
We added the id
property to the emp
object, so there is an overlap between
the Employee
type and the object, which also solves the error.
The error can also be solved by using an index signature.
interface Employee { id?: number; salary?: number; [key: string]: any; // ๐๏ธ added index signature } function getEmployee(emp: Employee) { return emp; } const emp = { name: 'Bobby Hadz', }; // ๐๏ธ {name: 'Bobby Hadz'} console.log(getEmployee(emp));
The {[key: string]: any}
syntax is an
index signature in TypeScript and is used
when we don't know all the names of a type's properties and the shape of the
values ahead of time.
Employee
is indexed with a string
, it will return a value of any
type.You don't have to use any
as the type, you can be much more specific for
better type safety. However, note that the type of the index signature has to be
a union type of all of the
possible types in the interface.
interface Employee { id?: number; salary?: number; // ๐๏ธ index signature with better type safety [key: string]: string | number | undefined; } const e: Employee = {}; function getEmployee(emp: Employee) { return emp; } const emp = { name: 'James', }; // ๐๏ธ {name: 'James'} console.log(getEmployee(emp));
We specified that when an object of type Employee
is indexed with a string
key, it will return a value of type string
, number
or undefined
.
id
and salary
properties have values of type number
or undefined
(because they are optional), and the id
and salary
are also string keys.This approach resolves the error because now there is an overlap between the
Employee
type and the emp
variable because the Employee
type now covers
any string key.
You can learn more about the related topics by checking out the following tutorials: