检查对象是否在 TypeScript 中实现接口

检查一个对象是否在 TypeScript 中实现了一个接口

Check if an Object implements an interface in TypeScript

使用用户定义的类型保护来检查对象是否实现了 TypeScript 中的接口。

用户定义的类型保护由一个函数组成,该函数检查传入的对象是否包含特定属性并返回类型谓词。

索引.ts
interface Employee { id: number; name: string; salary: number; } function isAnEmployee(obj: any): obj is Employee { return 'id' in obj && 'name' in obj && 'salary' in obj; } const emp: Employee = { id: 1, name: 'Bobby Hadz', salary: 100, }; console.log(isAnEmployee(emp)); // 👉️ true console.log(isAnEmployee({ id: 1 })); // 👉️ false if (isAnEmployee(emp)) { // 👉️ TypeScript knows that emp is type Employee console.log(emp.id); // 👉️ 1 console.log(emp.name); // 👉️ "Bobby Hadz" console.log(emp.salary); // 👉️ 100 }

我们使用
用户定义的类型保护
来检查对象是否实现了接口。

语法obj is Employee是类型谓词,其中必须是函数采用的参数的名称。 obj

如果isAnEmployee函数返回true,TypeScript 知道提供的值是类型的Employee,并允许我们访问特定接口上的所有属性和方法。

该示例只是检查传入的对象是否包含id,name
salary属性。

索引.ts
function isAnEmployee(obj: any): obj is Employee { return 'id' in obj && 'name' in obj && 'salary' in obj; }
根据您的用例,您可能需要更加严格,不仅要检查属性是否存在,还要检查值的类型。

如果您的界面有很多属性,这可能会变得非常冗长

检查对象是否使用type属性实现了接口

type另一种方法是向接口添加一个属性,您将检查该属性。

索引.ts
interface Employee { id: number; name: string; salary: number; type: 'Employee'; // 👈️ add type property } function isAnEmployee(obj: any): obj is Employee { // 👇️ check for type property return 'type' in obj && obj.type === 'Employee'; } const emp: Employee = { id: 1, name: 'Bobby Hadz', salary: 100, type: 'Employee', }; console.log(isAnEmployee(emp)); // 👉️ true console.log(isAnEmployee({ id: 1 })); // 👉️ false if (isAnEmployee(emp)) { console.log(emp.id); // 👉️ 1 console.log(emp.name); // 👉️ "Bobby Hadz" console.log(emp.salary); // 👉️ 100 console.log(emp.type); // 👉️ "Employee" }

Employee接口有一个type值为 的属性Employee

这意味着具有类型的所有对象都Employee将具有此属性。

我们在函数中要做的就是检查传入的对象是否具有等于 的属性 typeEmployee

我还写了一篇关于
如何基于接口创建对象的文章。

围绕从其他接口扩展的接口工作

但是,请注意,如果您有从Employee.

索引.ts
interface Employee { id: number; name: string; salary: number; type: 'Employee'; // 👈️ add type property } // ⛔️ Error: Interface 'Accountant' incorrectly // extends interface 'Employee'. // Types of property 'type' are incompatible. interface Accountant extends Employee { type: 'Accountant'; }

您不能简单地覆盖界面type中的属性Accountant

如果您必须这样做,您需要将type属性设置为 a string,但如果您有深层嵌套结构,这将很难管理。

想了解更多关于在 TypeScript 中使用接口的信息吗? 查看这些资源: 如何设置 TypeScript 接口默认值在 TS 中的接口和类中声明 getter/setter

用户定义的类型保护是更好的解决方案

用户定义的类型保护非常有用,尤其是当您必须检查一个对象是否是您事先知道的多种类型之一时。

索引.ts
interface Dog { bark(): void; } interface Cat { meow(): void; } const dog: Dog = { bark() { console.log('woof'); }, }; const cat: Cat = { meow() { console.log('meow'); }, }; function isDog(pet: Dog | Cat): pet is Dog { return 'bark' in pet; } function getPet(): Dog | Cat { return Math.random() > 0.5 ? dog : cat; } const pet = getPet(); if (isDog(pet)) { console.log(pet.bark()); } else { // 👉️ TypeScript knows pet is Cat console.log(pet.meow()); }

isDog()示例中的函数采用类型为 or 的参数DogCat
检查传入的参数是否为
Dog.

请注意,我们可以在if块中访问特定于狗的属性,并且在
else块中,TypeScript 知道如果pet不是 a Dog,那么它将是类型Cat

我还写了一篇关于
如何检查对象中是否存在属性的文章。

如果您需要按值获取对象的键,请单击以下
链接