我想实现一个泛型方法,它根据对象拥有的接口返回一个包含的值。但是我不知道该怎么做,我研究了typeof和interfaceof,但不确定如何实现它来满足下面的逻辑。
例如:
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;
}下面是工作代码的例子:
const dog: Animal = {
name: 'Rex'
};
const ferrari: Vehicle = {
model: 'Spider'
};
console.log(getDesignation<Vehicle>(ferrari)); /// prints Spider
console.log(getDesignation<Animal>(dog) /// prints Rex发布于 2021-02-20 12:35:31
正如@kaya3所说,typescript类型只存在于编译时,所以你不能在运行时检查interface。相反,您需要查看一个对象,并通过使用类型保护来确定它是否满足您想要的interface。
关键字in是一个built-in type guard,所以您可以这样做:
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
const isAnimal = <T extends {}>(value: T & {name?: any}): value is T & Animal => {
return typeof value.name === "string";
}如果它有一个string属性model,我们就知道它是一个Vehicle
const isVehicle = <T extends {}>(value: T & {model?: any}): value is T & Vehicle => {
return typeof value.model === "string";
}您可以使用以下函数来保护变量的类型:
const getDesignation = (data: Animal | Vehicle): string => {
if (isAnimal(data)) {
return data.name;
} else {
return data.model;
}
}发布于 2021-02-20 19:45:46
一种略微不同的方法是为每个您想要使用此指定逻辑的接口引入一个新接口:
interface HasDesignation {
getDesignation: () => string
}
interface Animal extends HasDesignation {
name: string;
}
interface Vehicle extends HasDesignation {
model: string;
}现在,您可以像这样构造实例:
const createAnimal = (name: string): Animal => ({
name,
getDesignation() { return this.name }
})
const createVehicle = (model: string): Vehicle => ({
model,
getDesignation() { return this.model }
})getDesignation变得非常简单:
const getDesignation = <T extends HasDesignation>(data: T): string => data.getDesignation()`https://stackoverflow.com/questions/66287155
复制相似问题