【问题标题】:Type guard for union type (Function | RegExp) does not work联合类型(函数 | RegExp)的类型保护不起作用
【发布时间】:2017-04-20 22:58:58
【问题描述】:

此代码似乎导致编译错误(使用 TypeScript 1.6.2 检查):

var a: ((input: any) => boolean) | string | RegExp = "foobar";
if (typeof a === 'function') {
    a(100); // compile error here
}

编译器说error TS2349: Cannot invoke an expression whose type lacks a call signature.

我在 TS Playground 中输入了这个,发现 a 在 if 子句中有一个 ((input: any) => boolean) | RegExp 类型,这不是我所期望的。当然typeof /abc/返回'object',所以我相信a不应该是if子句中的正则表达式。

我猜这在某种程度上与this issue 和“积极的亚型减少”有关,但我不确定。

显式类型断言 ((<Function>a)(100)) 没有解决我的问题。有没有快速的解决方法?

编辑:更新了问题,因为事实证明这不是特定于 1.6 的问题。

【问题讨论】:

    标签: typescript


    【解决方案1】:

    编辑:使用 typeof 的函数的类型保护在 TS 2.0+ 中工作。这应该不再是问题了。

    所以正如下面问题中指出的,目前支持的方式是使用instanceof...

    var a: ((input: any) => boolean) | string | RegExp = "foobar";
    
    if (a instanceof Function) {
        a(100); // ok
    }
    

    不过,#4868 中有一些关于支持使用 typeof 的新讨论。


    原答案

    你说的对我来说确实是个错误。

    现在,您可以使用用户定义的类型保护:

    function isFunction(obj: any) : obj is Function {
        return typeof obj === "function";
    }
    
    if (isFunction(a)) {
        a(10);
    }
    

    或者断言到any类型,然后断言到函数的类型:

    (a as any as (input: any) => boolean)(100);
    

    我已经打开 issue #4850 来询问这个问题。

    【讨论】:

    • 谢谢,我想我会暂时使用双类型断言。 (但我想知道为什么它会起作用......这是其他地方描述的众所周知的技术吗?)
    • @naruto 这是 1.6 中的新功能。我不确定为什么它会起作用,而不是常规的类型保护。我们会看看他们在这个问题上是怎么说的。
    猜你喜欢
    • 2020-01-14
    • 2017-05-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-02-13
    • 2018-10-02
    • 2020-06-27
    • 1970-01-01
    相关资源
    最近更新 更多