TS中不识别自己封装的类型判断

本文最后更新于:几秒前

在大型项目中我们更愿意使用ts取代js,其中一个主要原因是ts能够进行静态类型检查,提高代码质量。

比如当我们对一个对象进行push操作时,ts会先判断当前对象是否是一个数组。就像这样:

image-20201211141434434

这样能够比较安全的操作一些参数,然而我们可能进行一些类型校验的封装,比如下面的代码:

function isArray(arr): boolean {
    return Array.isArray(arr);
}

function isFunction(fn: any): boolean {
    return typeof fn === 'function';
}

然而,如果这样封装之后,ts并不买账你的类型判断:

image-20201211141925858

这种情况下怎么办呢?


解决方案

有两种解决方案:

  1. 一种是强行断言
function foo(arg: Array<number> | undefined) {
    arg.push(1);
    if (isArray(arg)) {
        (arg as Array<number>).push(1);
    }
    if (Array.isArray(arg)) {
        arg.push(1);
    }
}

这并不是一种优雅的选择。

  1. 修改isFunction等判断类型函数的返回值
function isArray(arr): arr is Array<any> {
    return Array.isArray(arr);
}

function isFunction(fn: any): fn is Function {
    return typeof fn === 'function';
}

function foo(arg: Array<number> | undefined) {
    arg.push(1);         // TS2532: Object is possibly 'undefined'.
    if (isArray(arg)) {
        arg.push(1);
    }
    if (Array.isArray(arg)) {
        arg.push(1);
    }
}

至此,问题解决。

备注

但是ts默认是不校验nullundefined的。除非我们修改ts.config.json中的strictNullChecks字段。"strictNullChecks": true。建议开启此配置项,能够进一步提高代码的严谨性。


本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!