类型 ‘X’ 与 TS 中的类型 ‘Y’ 没有共同的属性
Type ‘X’ has no properties in common with type ‘Y’ in TS
当我们在属性没有重叠的情况下尝试将任何内容分配给弱类型时,会出现错误“类型‘X’没有类型‘Y’的属性”。
要解决该错误,请声明任何重叠属性(如果存在)或使用类型断言。
下面是错误如何发生的示例。
// 👇️ 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);
该Employee
类型是
弱类型,因为它的所有属性都是可选的。
问号用于将类型的属性标记为
可选
,表示该属性可以是指定类型或是
undefined
.
该Employee
类型是弱类型,因为您可以创建一个
符合该类型的空对象。
interface Employee { id?: number; salary?: number; } // ✅ This is ok const e: Employee = {};
错误的原因是我们将emp
对象传递给期望类型对象的函数Employee
,并且emp
变量
与类型没有重叠Employee
。
使用类型断言解决错误
解决错误的一种方法是使用
类型断言。
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
肯定是 type Employee
。确保类型和对象之间有重叠
另一种解决方案是确保
Employee
类型和emp
对象之间存在重叠。
例如,我们可以将name
属性添加到类型中Employee
。
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));
我们将name
属性添加到Employee
类型,因此现在类型和对象之间存在重叠emp
。
如果您无法更改类型,则可以向对象添加重叠属性。
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));
我们id
给对象加上了属性,所以类型和对象emp
有重叠,也解决了这个错误。Employee
使用索引签名解决错误
该错误也可以通过使用索引签名来解决。
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));
该{[key: string]: any}
语法是
TypeScript 中的索引签名,当我们事先不知道类型属性的所有名称和值的形状时使用。
Employee
string
any
您不必使用any
as 类型,您可以更加具体以获得更好的类型安全性。但是,请注意索引签名的类型必须是接口中所有可能类型的联合类型。
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.
# Additional Resources
You can learn more about the related topics by checking out the following
tutorials: