无法将Typescript函数输出分配给条件类型
我有一个更复杂问题的简化版本。以下情况导致TSC抛出错误:无法将Typescript函数输出分配给条件类型,typescript,conditional-types,function-signature,Typescript,Conditional Types,Function Signature,我有一个更复杂问题的简化版本。以下情况导致TSC抛出错误: type Demo=isTrue扩展为true?{a:string}:isTrue扩展为false?{b:string}:从不; 常量func=(参数:T):演示=>{ 如果(arg){ 返回{a:“你好”}; }否则{ 返回{b:“世界”}; } }; const out=func(真); 抛出以下错误: 类型“{a:string;}”不能分配给类型“Demo”。 类型“{b:string;}”不可分配给类型“Demo”。 底部的
type Demo=isTrue扩展为true?{a:string}:isTrue扩展为false?{b:string}:从不;
常量func=(参数:T):演示=>{
如果(arg){
返回{a:“你好”};
}否则{
返回{b:“世界”};
}
};
const out=func(真);
抛出以下错误:
类型“{a:string;}”不能分配给类型“Demo”。
类型“{b:string;}”不可分配给类型“Demo”。
底部的out
在检查时具有正确的类型,因此只有函数定义存在问题。我如何更好地理解这一点,如何解决它
我添加了重载和
Demo
作为返回类型
在这种特殊情况下,T扩展布尔值
实际上与Demo
相同
但是请记住,泛型是很棘手的<代码>扩展并不意味着相等
type Demo=isTrue扩展为true?{a:string}:isTrue扩展为false?{b:string}:从不;
函数func(参数:false):演示
函数func(arg:true):演示
函数func(arg:boolean):演示{
如果(arg==true){
常数a=arg;
返回{a:“你好”};
}否则{
返回{b:“世界”};
}
};
const out=func(真);
我添加了重载和
Demo
作为返回类型
在这种特殊情况下,T扩展布尔值
实际上与Demo
相同
但是请记住,泛型是很棘手的<代码>扩展并不意味着相等
type Demo=isTrue扩展为true?{a:string}:isTrue扩展为false?{b:string}:从不;
函数func(参数:false):演示
函数func(arg:true):演示
函数func(arg:boolean):演示{
如果(arg==true){
常数a=arg;
返回{a:“你好”};
}否则{
返回{b:“世界”};
}
};
const out=func(真);
我怎样才能更好地理解这一点
看一看(另请参阅)。归结起来,TypeScript在使用条件类型时不支持缩小函数返回类型的范围。由于Demo
类型的解析取决于泛型类型参数T
,因此与直接在返回类型注释中写入条件相同
如果我们重写Demo
类型(仅用于演示目的),问题就会变得更清楚:
类型D={
正确:{
a:字符串
},
错误:{
b:字符串
}
}[`${T}`];
常量func=(参数:T):D=>{
如果(arg){
返回{a:“hello”};//类型{a:string;}不可分配给类型{a:string;}&{b:string;}”
}否则{
返回{b:world};//类型{b:string;}不可分配给类型{a:string;}&{b:string;}'
}
};
现在应该非常清楚的是,D
在您为类型参数提供一个参数之前一直没有得到解决。这就是为什么const out=func(true)代码>已正确推断
我如何解决它
您几乎只限于使用类型断言,如作为演示
,或者删除泛型类型参数并使用重载重写签名,如答案中所述
我怎样才能更好地理解这一点
看一看(另请参阅)。归结起来,TypeScript在使用条件类型时不支持缩小函数返回类型的范围。由于Demo
类型的解析取决于泛型类型参数T
,因此与直接在返回类型注释中写入条件相同
如果我们重写Demo
类型(仅用于演示目的),问题就会变得更清楚:
类型D={
正确:{
a:字符串
},
错误:{
b:字符串
}
}[`${T}`];
常量func=(参数:T):D=>{
如果(arg){
返回{a:“hello”};//类型{a:string;}不可分配给类型{a:string;}&{b:string;}”
}否则{
返回{b:world};//类型{b:string;}不可分配给类型{a:string;}&{b:string;}'
}
};
现在应该非常清楚的是,D
在您为类型参数提供一个参数之前一直没有得到解决。这就是为什么const out=func(true)代码>已正确推断
我如何解决它
您几乎只能使用类型断言,如作为演示
,或者删除泛型类型参数并用重载重写签名,如回答中所述。除了真
之外,还有什么扩展了真
?我认为没有,所以在这个特殊的例子中,我认为func
需要泛型或重载,但不是两者都需要。重载为noT
:当然,我只是没有从重载中删除泛型。除了true
,还有什么扩展了true
?我认为没有,所以在这个特殊的例子中,我认为func
需要泛型或重载,但不是两者都需要。noT
重载:当然,我只是没有从重载中删除泛型谢谢,我之所以选择这个作为答案,是因为这些讨论的链接实际上回答了我的问题,即为什么重载是解决这个问题的唯一方法,而不是条件返回类型。@aditya-NP,我记得在讨论之前,我花了很长时间问自己同样的问题。这是一个不幸的设计限制,从长远来看,它看起来会被重新考虑(毕竟,这里的推论确实有效)谢谢你,我之所以选择这个作为答案,是因为这些讨论的链接实际上回答了我的问题,即为什么超载是最重要的