首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >检查接口类型

检查接口类型
EN

Stack Overflow用户
提问于 2021-02-20 09:40:51
回答 2查看 33关注 0票数 0

我想实现一个泛型方法,它根据对象拥有的接口返回一个包含的值。但是我不知道该怎么做,我研究了typeof和interfaceof,但不确定如何实现它来满足下面的逻辑。

例如:

代码语言:javascript
复制
export interface Animal {
  name: string;
}

export interface Vehicle {
  model: string;
}

getDesignation<T>(data: T): string {

// if data has ANIMAL interface on it
// return data.name;

// if data has VEHICLE interface on it
// return data.model;
}

下面是工作代码的例子:

代码语言:javascript
复制
const dog: Animal = {
  name: 'Rex'
};

const ferrari: Vehicle = {
  model: 'Spider'
};

console.log(getDesignation<Vehicle>(ferrari)); /// prints Spider
console.log(getDesignation<Animal>(dog)  /// prints Rex
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2021-02-20 12:35:31

正如@kaya3所说,typescript类型只存在于编译时,所以你不能在运行时检查interface。相反,您需要查看一个对象,并通过使用类型保护来确定它是否满足您想要的interface

关键字in是一个built-in type guard,所以您可以这样做:

代码语言:javascript
复制
const getDesignation = (data: Animal | Vehicle): string => {
    if ('name' in data) {
        return data.name;
    } else {
        return data.model;
    }
}

我实际上有点惊讶这个编译,因为你可以有一个带有{name: number}Vehicle,但是它是seems to work的。使用XOR而不是Animal | Vehicle可以获得更好的类型安全性。

对于更复杂的用例,您可以创建自己的user-defined type guards

如果它有一个string属性name,我们就知道它是一个Animal

代码语言:javascript
复制
const isAnimal = <T extends {}>(value: T & {name?: any}): value is T & Animal => {
    return typeof value.name === "string";
}

如果它有一个string属性model,我们就知道它是一个Vehicle

代码语言:javascript
复制
const isVehicle = <T extends {}>(value: T & {model?: any}): value is T & Vehicle => {
    return typeof value.model === "string";
}

您可以使用以下函数来保护变量的类型:

代码语言:javascript
复制
const getDesignation = (data: Animal | Vehicle): string => {
    if (isAnimal(data)) {
        return data.name;
    } else {
        return data.model;
    }
}

Playground Link

票数 2
EN

Stack Overflow用户

发布于 2021-02-20 19:45:46

一种略微不同的方法是为每个您想要使用此指定逻辑的接口引入一个新接口:

代码语言:javascript
复制
interface HasDesignation {
    getDesignation: () => string
}


interface Animal extends HasDesignation {
  name: string;
}

interface Vehicle extends HasDesignation {
  model: string;
}

现在,您可以像这样构造实例:

代码语言:javascript
复制
const createAnimal = (name: string): Animal => ({
    name,
    getDesignation() { return this.name }
})

const createVehicle = (model: string): Vehicle => ({
    model,
    getDesignation() { return this.model }
})

getDesignation变得非常简单:

代码语言:javascript
复制
const getDesignation = <T extends HasDesignation>(data: T): string => data.getDesignation()`

Playground

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/66287155

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档