提问人:aditya 提问时间:2/22/2021 最后编辑:Oleg Valter is with Ukraineaditya 更新时间:3/7/2021 访问量:476
Typescript 函数输出不能分配给条件类型
Typescript function output cannot be assigned to conditional type
问:
我有一个更复杂问题的简化版本。以下原因导致 TSC 引发错误:
type Demo<isTrue> = isTrue extends true ? { a: string } : isTrue extends false ? { b: string } : never;
const func = <T extends boolean>(arg: T): Demo<T> => {
if (arg) {
return {a: "hello" };
} else {
return { b: "world" };
}
};
const out = func(true);
引发以下错误:
Type '{ a: string; }' is not assignable to type 'Demo<T>'.
Type '{ b: string; }' is not assignable to type 'Demo<T>'.
底部的检查类型正确,因此只有函数定义有问题。我怎样才能更好地理解这个问题,我该如何解决它?out
答:
2赞
captain-yossarian from Ukraine
2/22/2021
#1
我添加了重载和返回类型。Demo<boolean>
在这种特殊情况下,实际上与 .T extends boolean
Demo<boolean>
但请记住,泛型很棘手。 并不意味着.extends
equal
type Demo<isTrue> = isTrue extends true ? { a: string } : isTrue extends false ? { b: string } : never;
function func(arg: false): Demo<false>
function func(arg: true): Demo<true>
function func(arg: boolean): Demo<boolean> {
if (arg === true) {
const a = arg;
return { a: "hello" };
} else {
return { b: "world" };
}
};
const out = func(true);
评论
1赞
Linda Paiste
2/22/2021
除了什么?我认为没有,所以在这种特殊情况下,我认为这需要泛型或重载,但不能两者兼而有之。重载无 : tsplay.dev/rw2Rxwextends true
true
func
T
0赞
captain-yossarian from Ukraine
2/22/2021
当然,我只是没有从重载中删除泛型
3赞
Oleg Valter is with Ukraine
2/22/2021
#2
我怎样才能更好地理解这一点?
看看这个 GitHub 线程(另请参阅原始问题)。归根结底,TypeScript 在使用条件类型时不支持缩小函数返回类型的范围。由于类型的解析取决于泛型类型参数,这与直接在返回类型注解中编写条件相同。Demo
T
如果我们重写类型(仅用于演示目的),问题应该会变得更加清晰:Demo
type D<T extends boolean> = {
true: {
a: string
},
false: {
b: string
}
}[`${T}`];
const func = <T extends boolean>(arg: T): D<T> => {
if (arg) {
return {a: "hello" }; //Type '{ a: string; }' is not assignable to type '{ a: string; } & { b: string; }'
} else {
return { b: "world" }; //Type '{ b: string; }' is not assignable to type '{ a: string; } & { b: string; }'
}
};
现在,在您为 type 参数提供参数之前,它应该非常清楚,它仍然未解决。这就是为什么正确推断的原因。D<T>
const out = func(true);
我该如何解决?
您几乎只能使用类型断言,例如删除泛型类型参数并使用重载重写签名,如 captain-yossarian 的回答中所述。as Demo<T>
评论
1赞
aditya
2/24/2021
谢谢,我之所以选择这个作为答案,是因为讨论的链接实际上回答了我的问题,即为什么重载是解决这个问题的唯一方法,而不是条件返回类型。
0赞
Oleg Valter is with Ukraine
2/24/2021
@aditya - NP,我记得在偶然讨论之前,我花了很长时间问自己同样的问题。一个不幸的设计限制,从长远来看,看起来会重新考虑(毕竟,推理在这里确实有效)
评论