【问题标题】:Integer (literal) union type, with NaN as valid return value整数(文字)联合类型,以 NaN 作为有效返回值
【发布时间】:2017-12-07 14:46:13
【问题描述】:

我有一个联合返回类型的(比较)函数。它可以返回-110。但是,我需要一个特殊情况(“结果”),用于当至少一个被比较的项目没有定义时。编译器允许我添加 null 作为潜在的返回值,但不能添加 NaN(在某些情况下这会有意义,例如比较数字或日期)。

这样编译

function myFunc(item1: MyType, item2: MyType): -1 | 0 | 1 | null {
   ...
}

但是对于这个,编译器说“找不到名称 NaN”:

function myFunc(item1: MyType, item2: MyType): -1 | 0 | 1 | NaN {
   ...
}

为什么不允许NaN?有没有办法使用NaN

【问题讨论】:

  • NaN 不是 int 它是浮点数,这可能是 TS 不喜欢它的原因。
  • @mfeine 是肯定的,但是这个function bla(): 1 | "3" | null { ... }也可以编译。
  • JavaScript 在 int 和 float 之间没有区别。两者都是同一类型Number。我认为 NaN 也是Number
  • 我敢打赌 1 | "3" | null 被推断为任何类型。文字类型是一种 TS 特性,它们可能有自己的规则 :-)
  • 是的,我的意思是文字类型“不需要”是同一类型。

标签: typescript typescript2.0


【解决方案1】:

1 不同,NaN 不能用作literal type(即只包含该字面值的类型)。

const n1 = 1, n2 = NaN;
typeof n1; // 1
typeof n2; // number

我们也可以使用number 作为返回类型,但这将允许更多返回值,例如-2。如果你想限制选项,null 对我来说很好。

【讨论】:

    【解决方案2】:

    NaN 本身不是类型,而是const 类型的Number 值。所以没有办法将任何东西定义为 NaN 类型。

    这是有道理的,因为数字的文字类型都是单个值,例如-1,或文字值 1 | 0 | -1 的并集,但 NaN 不是单个值,因为没有 NaN 可以与任何其他值进行比较,它实际上是一组无限的值。

    我建议使用NaN 来指示函数的特定结果是一个坏主意,因为您可以测试获得该结果的唯一方法是调用另一个函数。最好将 nullundefined 添加到返回类型(或者如果您不喜欢这样,那么文字字符串如何)。

    请记住:

    let foo = NaN;
    switch(foo) {
        case 1: console.log('got 1'); break
        case NaN: console.log('got NaN'); break;
        default: console.log('other');
    }
    

    将输出“其他”。

    所以你可以这样做:

    function myFunc(item1: MyType, item2: MyType): -1 | 0 | 1 | 'not comparable' {
       ...
    }
    

    然后您可以将结果与“不可比较”进行比较。

    【讨论】:

    • 抛开函数的作用域(这更多的是一个例子,而不是实际的问题——我最终使用了null)。事实是,我可以将所有值(-101NaN)视为常量。反过来,这意味着我有一个函数应该能够从一组特定的值中返回一个(常量)值。 TS 编译器不同意...
    • 是的,但我的观点是 NaN 不是一个单一的值,而是一个值的类别。
    • 作为一个值类并不排除它是一个类型;毕竟,类是类型。只是它不是类型;可能是,但不是。 GitHub 上有一个proposal to make it a type
    猜你喜欢
    • 2022-11-17
    • 2022-12-18
    • 2012-12-11
    • 2015-06-12
    • 2019-09-10
    • 2018-05-28
    • 1970-01-01
    • 2021-04-02
    • 1970-01-01
    相关资源
    最近更新 更多