Typescript自动计算if语句的类型基础

时间:2018-02-02 13:03:14

标签: javascript typescript

我们说我有一个带有以下签名的功能。

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;

3 个答案:

答案 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。在这种情况下,只需将其分为两个具有不同返回类型的函数。两者甚至可以依赖于封装两者之间共同行为的第三个函数。不过要回答这个问题,在这种情况下,我不知道有什么方法可以做到这一点。这是编译器制作的复杂推理。

  • 如果您希望它能够找出传入的任意数据的类型,那将是不可能的。如果在运行时为其提供用户提供的数据,则它无法在编译时推断出类型。你要求它根据它没有的信息做出决定。