gpt4 book ai didi

typescript :为什么这个微不足道的泛型函数的行为不像它的非泛型等价物?

转载 作者:搜寻专家 更新时间:2023-10-30 21:20:56 25 4
gpt4 key购买 nike

type Greeting = { name: "Hello" } | { name: "Hi!" };

export function foo(name_of_greeting: Greeting["name"]): Greeting {
return { name: name_of_greeting };
}

export function bar<N extends Greeting["name"]>(name_of_greeting: N): Greeting {
return { name: name_of_greeting };
}

foo 类型检查正常,但 bar 产生以下错误:

Type '{ name: N; }' is not assignable to type 'Greeting'.

天真地,我希望 bar 完全等同于 foo。为什么 TypeScript 不同意?

最佳答案

TypeScript 编译器通常不会将具有联合类型属性的对象类型分解为具有非联合属性的对象类型的联合。在 TypeScript 3.5 之前,根本没有(both functions fail in TS3.3)。引入了 TypeScript 3.5 "smarter" union type checking其中某些具体属性联合有时会以这种方式检查...并且您的foo() 函数编译成功。

理论上,总是可以将联合对象分解为对象联合:例如,{a: string|number; b: bool 值; c: 对象 | null} 可以分解为 {a: string, b: true, c: object} | {a:字符串,b:真,c:空} | {a:字符串,b:假,c:对象} | {a:字符串,b:假,c:空} | {a:数字,b:真,c:对象} | {a:数字,b:真,c:空} | {a:数字,b:假,c:对象} | {a:数字,b:假,c:空})。但是,这可能会造成巨大的性能损失,并且只会在某些用例中有益。

我假设当类型是泛型时,操作联合类型的属性会更加困难/昂贵,其中 {a: T} where T extends 0 | 1 将是一些通用类型 U extends {a: never} | {一:0} | {a: 1}。所以语言还没有做到。这可以考虑 intentionaldesign limitation typescript 。


无论如何,我的解决方法是将 bar() 中的返回值扩展为编译器正确检查的具体类型,如下所示:

export function bar<N extends Greeting["name"]>(name_of_greeting: N): Greeting {
const concreteGreeting: { name: "Hello" | "Hi!" } = {
name: name_of_greeting
};
return concreteGreeting;
}

好的,希望对你有帮助;祝你好运!

Link to code

关于 typescript :为什么这个微不足道的泛型函数的行为不像它的非泛型等价物?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57792370/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com