下面的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
}
};
将鼠标悬停在波浪线上,这是我得到的错误:
Type '{ humanName: string; }' is not assignable to type 'TItem extends Human ? HumanName : AnimalName'.ts(2322)
这是 playground link .
片段的灵感来自于传奇人物 Matt Pocock 的 tips .
最佳答案
你的问题是在函数实现中,泛型类型是unresolved,所以你不能把它当作一个Animal
或者作为 Human
而无需显式转换。
泛型类型仅为调用者解析。
您的问题的一个可能解决方案是利用 function overloads为了写两个签名:
- 一个为调用者强类型
- 一个松散类型的实现(在 duck typing 方面与第一个兼容)
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
关于typescript - 函数返回类型不可分配给泛型解析的内容,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/73586791/