typeof 类型保护在分配给变量时是不是不起作用?

Posted

技术标签:

【中文标题】typeof 类型保护在分配给变量时是不是不起作用?【英文标题】:Does typeof typeguard not work when assigned to a variable?typeof 类型保护在分配给变量时是否不起作用? 【发布时间】:2018-10-22 13:20:25 【问题描述】:

当我使用typeof 时出现错误,如下所示。

function func (variable: number | string) 
    const is_number = (typeof variable === 'number');
    let variable2: number,
        variable3: string;

    if (is_number)
        variable2 = variable;
        => Type 'string | number' is not assignable to type 'number'.
           Type 'string' is not assignable to type 'number'.
    else
        variable3 = variable;
        => Type 'string | number' is not assignable to type 'string'.
           Type 'number' is not assignable to type 'string'.

但是,没有像下面这样的错误。

function func (variable: number | string) 
    let variable2: number,
        variable3: string;

    if (typeof variable === 'number')
        variable2 = variable;
    else
        variable3 = variable;

URL for test

我总是必须像上面那样使用它吗?还是我用错了什么部分?

感谢阅读:)

【问题讨论】:

正确,它没有。编译器在识别这些模式方面只能走这么远。 @Ry- 你应该回答你的评论。也许参考公关?我会投票赞成:-) @TitianCernicova-Dragomir:什么公关? 【参考方案1】:

@Ry- 已经回答了 cmets 中的实际问题。以下是限制的解决方法。

可以使用我称为isNumber 的辅助函数来执行类似于您尝试实现的操作,该函数断言给定参数extends 是否是打字稿中的某种类型。毕竟,这提供了一种不内联像 typeof variable === "number" 这样的 JS 领域类型断言的方法。相反,断言现在包含在一个函数中。

这是使用x is y 构造完成的,称为Type predicate(您必须向下滚动一点)。在下面的sn-p中,isNumber的返回类型就是这样一个类型谓词:

const isNumber = (subject: any): subject is number => 
    return typeof subject === 'number';
;

在这里,typescript 可以从 isNumber 返回的布尔值推断出类型 number。现在,如果你在自己的func 中使用这个辅助函数,一切都会好起来的:

function func (variable: number | string) 
    let variable2: number;
    let variable3: string;

    if (isNumber(variable)) 
        variable2 = variable;
     else 
        variable3 = variable;
    

由于 if 块只有在 isNumber(variable) 返回 true 时才会执行,所以 Typescript 现在将假定 subject is number。下面的伪代码演示了上面的代码应该如何被 TS 解释:

if (variable is number) 
    // ...

我还找到了进一步解释类型谓词构造的this SO answer。

【讨论】:

以上是关于typeof 类型保护在分配给变量时是不是不起作用?的主要内容,如果未能解决你的问题,请参考以下文章

类变量分配在 Alamofire 请求块中不起作用

如何从 SQL Server 2014 中的 Select 查询中将数据分配给用户定义的表类型

在编写类型保护时,使用 `typeof` 的 `any` 的(正确)惯用替代方法是啥?

Angular 2 将表单分配给变量不起作用#f="form" (submit)="onSubmit(f.value)"

typeof EnforceAjax 不可分配给类型中间件

将字符串值分配给来自AsyncTask的onPostExecute方法的活动字符串变量不起作用