Typescript 接口继承和泛型类型推断
Typescript Interface Inheritance and Generics Type Infer
我有一个关于 TypeScript 接口、泛型、classess 的小问题...不确定是哪一个,或者我的脑袋被思考淹没了,我看不到简单的解决方案。
这是我的问题:
假设我有以下接口:
interface Animal {
legs: number;
}
interface Cat extends Animal {
meouw : string;
}
interface Dog extends Animal {
waf : stringl
}
我希望能够做这样的事情:
interface GenericAnimal { specimen : <T extends Animal> } ;
let someAnimals : GenericAnimal[] = [
{ specimen : {legs : 3, meouw : 'mrrrr'} } ,
{ specimen : {legs : 1, waf : 'hrrr' }
];
这样 GenericAnimal 接口只能有 'specimen'-s 扩展 Animal 接口,但是在初始化 GenericAnimal 实例时,我将能够通过 Intellisense 访问扩展接口的属性。
请注意,使用 GenericAnimal<T>
不是我的解决方案,因为我的 someAnimals 数组需要保存不同的 'animals' (假设我有超过 100 个)....使用联合类型也可能不是一个好的解决方案。你有什么建议?
还有什么方法可以在破坏数组(或遍历数组成员)后推断数组的每个项目的类型?Ty
如果您不想使用 discriminating union, you can use typeguards:
interface Animal {
legs: number;
}
function isAnimal(potentialAnimal: any): potentialAnimal is Animal {
return typeof potentialAnimal === "object" && "legs" in potentialAnimal && typeof potentialAnimal.legs === "number";
}
interface Cat extends Animal {
meouw: string;
}
function isCat(potentialCat: any): potentialCat is Cat {
return isAnimal(potentialCat) && "meouw" in potentialCat && typeof (potentialCat as Cat).meouw === "string"
}
interface Dog extends Animal {
waf: string;
}
function isDog(potentialDog: any): potentialDog is Dog {
return isAnimal(potentialDog) && "waf" in potentialDog && typeof (potentialDog as Dog).waf === "string"
}
interface GenericAnimal<T extends Animal = Animal> {
specimen: T
& Record<string, any> // Needed to stop extraneous prop check
};
let someAnimals: GenericAnimal[] = [
{
specimen: {
legs: 3,
meouw: 'mrrrr'
}
},
{
specimen: {
legs: 1,
waf: 'hrrr'
}
}
];
someAnimals.map((genericAnimal: GenericAnimal): Animal => {
return genericAnimal.specimen;
}).forEach(animal =>{
if(isCat(animal)){
console.log(animal.meouw);
} else if(isDog(animal)) {
console.log(animal.waf);
}
});
if(isCat(someAnimals[0].specimen)) {
console.log(someAnimals[0].specimen.meouw);
}
我有一个关于 TypeScript 接口、泛型、classess 的小问题...不确定是哪一个,或者我的脑袋被思考淹没了,我看不到简单的解决方案。 这是我的问题: 假设我有以下接口:
interface Animal {
legs: number;
}
interface Cat extends Animal {
meouw : string;
}
interface Dog extends Animal {
waf : stringl
}
我希望能够做这样的事情:
interface GenericAnimal { specimen : <T extends Animal> } ;
let someAnimals : GenericAnimal[] = [
{ specimen : {legs : 3, meouw : 'mrrrr'} } ,
{ specimen : {legs : 1, waf : 'hrrr' }
];
这样 GenericAnimal 接口只能有 'specimen'-s 扩展 Animal 接口,但是在初始化 GenericAnimal 实例时,我将能够通过 Intellisense 访问扩展接口的属性。
请注意,使用 GenericAnimal<T>
不是我的解决方案,因为我的 someAnimals 数组需要保存不同的 'animals' (假设我有超过 100 个)....使用联合类型也可能不是一个好的解决方案。你有什么建议?
还有什么方法可以在破坏数组(或遍历数组成员)后推断数组的每个项目的类型?Ty
如果您不想使用 discriminating union, you can use typeguards:
interface Animal {
legs: number;
}
function isAnimal(potentialAnimal: any): potentialAnimal is Animal {
return typeof potentialAnimal === "object" && "legs" in potentialAnimal && typeof potentialAnimal.legs === "number";
}
interface Cat extends Animal {
meouw: string;
}
function isCat(potentialCat: any): potentialCat is Cat {
return isAnimal(potentialCat) && "meouw" in potentialCat && typeof (potentialCat as Cat).meouw === "string"
}
interface Dog extends Animal {
waf: string;
}
function isDog(potentialDog: any): potentialDog is Dog {
return isAnimal(potentialDog) && "waf" in potentialDog && typeof (potentialDog as Dog).waf === "string"
}
interface GenericAnimal<T extends Animal = Animal> {
specimen: T
& Record<string, any> // Needed to stop extraneous prop check
};
let someAnimals: GenericAnimal[] = [
{
specimen: {
legs: 3,
meouw: 'mrrrr'
}
},
{
specimen: {
legs: 1,
waf: 'hrrr'
}
}
];
someAnimals.map((genericAnimal: GenericAnimal): Animal => {
return genericAnimal.specimen;
}).forEach(animal =>{
if(isCat(animal)){
console.log(animal.meouw);
} else if(isDog(animal)) {
console.log(animal.waf);
}
});
if(isCat(someAnimals[0].specimen)) {
console.log(someAnimals[0].specimen.meouw);
}