kst*_*tis 3 typescript typescript-generics
下面的TS代码有什么问题吗?
interface Animal {
name: string;
}
interface Human {
firstName: string;
lastName: string;
}
type HumanName = { humanName: string };
type AnimalName = { animalName: string };
export const getDisplayName = <TItem extends Animal | Human>(
item: TItem
): TItem extends Human ? HumanName : AnimalName => {
if ("firstName" in item) {
return { humanName: `${item.firstName} ${item.lastName}` }; // squiggly line
} else {
return { animalName: item.name }; // squiggly line
}
};
Run Code Online (Sandbox Code Playgroud)
将鼠标悬停在波浪线上,这是我得到的错误:
Type '{ humanName: string; }' is not assignable to type 'TItem extends Human ? HumanName : AnimalName'.ts(2322)
Run Code Online (Sandbox Code Playgroud)
这是游乐场链接。
片段灵感来自传奇人物 Matt Pocock 的技巧。
您的问题是,在函数实现中,泛型类型未解决,因此您不能将其视为 anAnimal或 aHuman而不显式转换它。
泛型类型仅为调用者解析。
解决您的问题的一种可能的解决方案是利用函数重载来编写两个签名:
interface Animal {
name: string;
}
interface Human {
firstName: string;
lastName: string;
}
type HumanName = { humanName: string };
type AnimalName = { animalName: string };
function getDisplayName<TItem extends Animal | Human>(item: TItem): TItem extends Human ? HumanName : AnimalName
function getDisplayName(item: Animal | Human): HumanName | AnimalName {
if ("firstName" in item) {
return { humanName: `${item.firstName} ${item.lastName}` }; // item: Human
} else {
return { animalName: item.name }; // item: Animal
}
}
const animalName = getDisplayName({ name: 'cat' }); // AnimalName
const humanName = getDisplayName({ firstName: 'Guerric', lastName: 'P' }); // HumanName
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
713 次 |
| 最近记录: |