我们说我有一个带有以下签名的功能。
function doSomething(bool = false): number | string {
if (bool) {
return '1';
} else {
return 1;
}
}
const value = doSomething();
const valueTwo = doSomething(true);
我的问题是type
变量的value
在两种情况下均为number | string
。如何在不执行类似操作的情况下告诉typescript基于if块返回正确的类型:
const value = doSomething() as number;
const valueTwo = doSomething(true) as string;
答案 0 :(得分:3)
您可以为函数设置多个签名,如果返回类型依赖于原始值,则可以使用文字类型进行区分。在你的情况下,你可以写:
// Public sigantures
function doSomething(bool?: false): number // With false constant
function doSomething(bool: true): string // With true constant or missing
function doSomething(bool?: boolean): number | string // With unknown bool value
// Implementation siganture
function doSomething(bool: boolean = false): number | string {
if (bool) {
return '1';
} else {
return 1;
}
}
var s = doSomething(true) // s is string
var n2 = doSomething() // n2 is number
var n3 = doSomething(false) // n3 is number
declare var b: boolean;
var ns4 = doSomething(b) // ns4 is string | number because it can't be determined at compile time
答案 1 :(得分:1)
TypeScript是一种静态类型语言 - 在编译时它可以理解代码中的类型定义,并通过检查您是否未获得类型来帮助查找错误。
当您将方法标记为返回number | string
时,您将提供编译器信息:您知道该方法将返回这两种可能类型之一。编译器没有能力详细查看该方法,以了解代码返回特定类型的条件。这就是我们必须告诉编译器方法签名中所有可能的返回类型的原因;它无法自行解决。
如果您希望编译器知道类型,可以使用过载签名为其提供更多信息,过载签名根据某些常量值区分返回类型:
function doSomething(bool: false): number
function doSomething(bool?: true): string
function doSomething(bool?: boolean): number | string
编译器现在可以根据布尔值的值来解析返回类型,但是只有在值为常量时才会这样做:在编译时已知。
这意味着这些语句具有已知的单一返回类型:
var str = doSomething(true);
var bool = doSomething(false);
但是这个调用没有:
declare var input: boolean;
var strOrBool = doSomething(input)
答案 2 :(得分:0)
不是直接的答案,但是:
如果您指的是手动传入文字时that would likely be a bad design; you're trying to have the function do too much。在这种情况下,只需将其分为两个具有不同返回类型的函数。两者甚至可以依赖于封装两者之间共同行为的第三个函数。不过要回答这个问题,在这种情况下,我不知道有什么方法可以做到这一点。这是编译器制作的复杂推理。
如果您希望它能够找出传入的任意数据的类型,那将是不可能的。如果在运行时为其提供用户提供的数据,则它无法在编译时推断出类型。你要求它根据它没有的信息做出决定。