提问人:Sheen 提问时间:10/20/2022 最后编辑:Sheen 更新时间:10/20/2022 访问量:47
在打字稿中,基于对象形状的类型推断是否可行?
Is type inference based off the shape of an object possible in typescript?
问:
假设我有 3 个接口:
interface Animal {
height: number
name: string
}
interface Dog extends Animal {
numberOfTeeth: number
hasTail: boolean
}
interface Cat extends Animal {
sizeOfPaw: number
}
假设我查询了一个这样的 api:
function getAnimal(id:string, animalType:string) : Animal {
const res = await (axios.get(`http://animalapi.com/${animalType}/${id}`));
return res.data; // Could be a cat, could be a dog, based on animal type
}
如果我尝试这样做:
const animal:Dog = getAnimal("1", "dog"); // Would it be possible to not need to pass the string dog? Perhaps store the "dog" value within the interface and pass it from there?
我收到错误“Animal 缺少以下类型”,然后是 Dog 中的类型。
是否有可能从同一个函数中同时获取 Dog 和 Cat,而不必重复调用?
答:
0赞
Aleksandr Hovhannisyan
10/20/2022
#1
在打字稿中,基于对象形状的类型推断是否可行?
是的,这被称为类型缩小,你可以用一个可区分的联合来做到这一点,该联合将 和 形状连接起来,但为每个形状提供一个唯一的“标签”,以将其与其他形状区分开来(这可能是一个属性,如 ,,或任何你想称呼它的东西):Dog
Cat
id
type
interface AnimalBase {
height: number
name: string
}
interface Dog extends AnimalBase {
type: 'dog';
numberOfTeeth: number
hasTail: boolean
}
interface Cat extends AnimalBase {
type: 'cat';
sizeOfPaw: number
}
type Animal = Dog | Cat;
现在,当您创建一个 ,TypeScript 将期望您通过指定属性来识别特定形状。然后,你可以随心所欲地传递,因为它是一个字符串文字:Animal
type
animal.type
const dog: Animal = {
type: 'dog',
numberOfTeeth: 100,
hasTail: true,
height: 100,
name: 'Roofus'
};
getAnimal("1", animal.type)
此模式还有一个额外的好处,即允许您将泛型类型缩小到特定的子类型。例如,您可以使用它来编写类型谓词,以检查动物是否属于特定成分类型:Animal
const isDog = (animal: Animal): animal is Dog => {
return animal.type === 'dog';
}
const dog: Animal = {
type: 'dog',
numberOfTeeth: 100,
hasTail: true,
height: 100,
name: 'Roofus'
};
// here, TypeScript knows that animal is now of type Dog
if (isDog(dog)) {
// myAnimal shape is now Dog
}
如果没有可区分的并集,你需要做一个类型断言,并检查一个你知道对狗来说绝对独特的属性(也许,但对猫来说也是如此):hasTail
const isDog = (animal: Animal): animal is Dog => {
return typeof (animal as Dog).numberOfTeeth !== 'undefined';
}
评论
axios
"dog"
"dog"
id
number
string
declare
"dog"
"cat"
Dog
Cat