为什么条件类型不能在泛型函数中工作



为什么TypeScript不能使用泛型函数的类型参数约束来推断参数类型或返回类型?

function isNum<T extends number>(x:T):T extends number?”Y”:”N”{
return “Y”; // <- error: type “Y” is not assignable to type ‘T extends number?”Y”:”N”’
}

除了分叉TS之外,还有什么方法可以达到预期的结果吗?

(使用TS 2.9.2(

在需要泛型类型的地方赋值通常不起作用,typescript假设该值不兼容。这是因为当我们有一个泛型类型时,该类型表示T的任何可能的子类型。

现在,在这种情况下,很明显T将始终是"Y",因为T上已经存在约束,但typescript不会试图推导出这一点。一个更明显的情况是不起作用的,因为typescript在这种情况下根本不会进行任何分析:

function isNum<T extends number>(x: T): T extends number ? "Y" : "Y" {
return "Y"; // still an error 
}

唯一的解决方案是使用类型断言:

function isNum<T extends number>(x: T): T extends number ? "Y" : "N" {
return "Y" as any;
}

编辑

正如@jcalz所指出的,另一个非常好的选择是使用多个重载(或者更具体地说,使用条件类型的公共重载,以及不使用条件类型实现的重载(

function isNum<T extends number>(x: T): T extends number ? "Y" : "N"
function isNum(x: number): "Y" | "N" {
return "Y";
}
不,Typescript还不支持条件返回类型。至于你的情况,你可以做以下几件事:

以枚举形式返回类型

enum YesNo {
Y= 'Y',
N= 'N'
}
function isNum<T extends Number>(x:T) : YesNo {
return x as any instanceof Number ? YesNo.Y : YesNo.N;
}

严格返回类型

function isNum<T extends Number>(x:T) : 'Y' | 'N' {
return x as any instanceof Number ? 'Y' : 'N';
}

如果您希望返回类型为特定类型

interface ANumber extends Number {
...
}
interface BNumber extends Number {
...
}
function isNum<T extends Number>(x:T) : ANumber | BNumber {
return x;
}

注意:以上接口也可以是类。

最新更新