Typescript return 类型取决于参数
Typescript return type depending on parameter
我正在尝试编写一个函数,该函数采用布尔类型和 returns 两种类型之一的参数,具体取决于输入值。我找到了两种方法:
function dependsOnParameter<B extends boolean>(x: B): B extends true ? number : string {
if (x) {
return 3;
} else {
return "string";
}
}
在这里,TypeScript 表示 Type '3'/'"string"' is not assignable to type 'B extends true ? number : string'.
我的其他方法是这样的:
function dependsOnParameter(x: true): number;
function dependsOnParameter(x: false): string;
function dependsOnParameter(x: boolean): number | string {
if (x) {
return 3;
} else {
return "string";
}
}
这个编译;但是,如果我尝试使用我的函数:
function calling(x: boolean) {
dependsOnParameter(x);
}
我得到 Argument of type 'boolean' is not assignable to parameter of type 'false'
。
有什么方法可以不使用 any
来达到我想要的效果吗?
两种方法都有效。如果您的函数在 return 中使用条件类型,则需要使用类型断言,因为 typescript 不会尝试推断条件类型,因为它包含一个自由类型参数:
function dependsOnParameter<B extends boolean>(x: B): B extends true ? number : string {
if (x) {
return 3 as any;
} else {
return "string"as any;
}
}
此方法使用了您想避免的 any
。
第二种方法我们可以在不诉诸类型断言的情况下开始工作,只需复制最后一个签名:
function dependsOnParameter(x: true): number;
function dependsOnParameter(x: false): string;
function dependsOnParameter(x: boolean): number | string
function dependsOnParameter(x: boolean): number | string {
if (x) {
return 3;
} else {
return "string";
}
}
function calling(x: boolean) {
dependsOnParameter(x); // returns number| string
dependsOnParameter(true); // returns number
dependsOnParameter(false); // returns string
}
最后一个签名是实现签名,不可公开访问。您可以通过复制它来使其可访问。编译器不够聪明,无法将两个重载与 true
/false
组合起来,并决定 return 类型为 string|number
编辑
我们还可以结合这两种方法来减少签名:
function dependsOnParameter<B extends boolean>(x: B): B extends true ? number : string
function dependsOnParameter(x: boolean): number | string{
if (x) {
return 3;
} else {
return "string";
}
}
可以这样写
function dependsOnParameter<B extends boolean, C = B extends true ? number : string>(x: B): C {
if (x) {
return 3 as unknown as C;
} else {
return "string" as unknown as C;
}
}
这是正确的方法:
function dependsOnParameter<B extends boolean>(x: B): B extends true ? number : string {
return (x === true ? 3 : "string") as B extends true ? number : string;
}
这里,条件本身(B extends true ? number : string)被认为是一种类型。这种类型称为 Conditional Type.
我正在尝试编写一个函数,该函数采用布尔类型和 returns 两种类型之一的参数,具体取决于输入值。我找到了两种方法:
function dependsOnParameter<B extends boolean>(x: B): B extends true ? number : string {
if (x) {
return 3;
} else {
return "string";
}
}
在这里,TypeScript 表示 Type '3'/'"string"' is not assignable to type 'B extends true ? number : string'.
我的其他方法是这样的:
function dependsOnParameter(x: true): number;
function dependsOnParameter(x: false): string;
function dependsOnParameter(x: boolean): number | string {
if (x) {
return 3;
} else {
return "string";
}
}
这个编译;但是,如果我尝试使用我的函数:
function calling(x: boolean) {
dependsOnParameter(x);
}
我得到 Argument of type 'boolean' is not assignable to parameter of type 'false'
。
有什么方法可以不使用 any
来达到我想要的效果吗?
两种方法都有效。如果您的函数在 return 中使用条件类型,则需要使用类型断言,因为 typescript 不会尝试推断条件类型,因为它包含一个自由类型参数:
function dependsOnParameter<B extends boolean>(x: B): B extends true ? number : string {
if (x) {
return 3 as any;
} else {
return "string"as any;
}
}
此方法使用了您想避免的 any
。
第二种方法我们可以在不诉诸类型断言的情况下开始工作,只需复制最后一个签名:
function dependsOnParameter(x: true): number;
function dependsOnParameter(x: false): string;
function dependsOnParameter(x: boolean): number | string
function dependsOnParameter(x: boolean): number | string {
if (x) {
return 3;
} else {
return "string";
}
}
function calling(x: boolean) {
dependsOnParameter(x); // returns number| string
dependsOnParameter(true); // returns number
dependsOnParameter(false); // returns string
}
最后一个签名是实现签名,不可公开访问。您可以通过复制它来使其可访问。编译器不够聪明,无法将两个重载与 true
/false
组合起来,并决定 return 类型为 string|number
编辑
我们还可以结合这两种方法来减少签名:
function dependsOnParameter<B extends boolean>(x: B): B extends true ? number : string
function dependsOnParameter(x: boolean): number | string{
if (x) {
return 3;
} else {
return "string";
}
}
可以这样写
function dependsOnParameter<B extends boolean, C = B extends true ? number : string>(x: B): C {
if (x) {
return 3 as unknown as C;
} else {
return "string" as unknown as C;
}
}
这是正确的方法:
function dependsOnParameter<B extends boolean>(x: B): B extends true ? number : string {
return (x === true ? 3 : "string") as B extends true ? number : string;
}
这里,条件本身(B extends true ? number : string)被认为是一种类型。这种类型称为 Conditional Type.