小编典典

打字稿中的`is`关键字有什么作用?

all

我遇到了一些看起来像这样的代码:

export function foo(arg: string): arg is MyType {
    return ...
}

我无法is在 docs 或 google 中搜索,这是一个非常常见的词,并且基本上出现在每个页面上。

关键字在这种情况下有什么作用?


阅读 119

收藏
2022-06-06

共1个答案

小编典典

有关更多信息,请参阅用户定义的类型保护函数的参考。

function isString(test: any): test is string{
    return typeof test === "string";
}

function example(foo: any){
    if(isString(foo)){
        console.log("it is a string" + foo);
        console.log(foo.length); // string function
    }
}
example("hello world");

test is string使用上述格式的类型谓词(而不是仅boolean用于返回类型),
afterisString()被调用,如果函数返回trueTypeScript 会将类型缩小到string由函数调用保护的任何块中。
编译器会认为它foo位于string保护之下的块中(并且仅在保护之下的块中)

{
    console.log("it is a string" + foo);
    console.log(foo.length); // string function
}

类型谓词仅在编译时使用。结果.js文件(运行时)将没有区别,因为它不考虑 TYPE。

我将在以下四个示例中说明差异。

例如1:上面的示例代码不会出现编译错误或运行时错误。

例如 2:下面的示例代码将出现编译错误(以及运行时错误),因为 TypeScript
已将类型缩小到string并检查了toExponential不属于string方法的情况。

function example(foo: any){
    if(isString(foo)){
        console.log("it is a string" + foo);
        console.log(foo.length);
        console.log(foo.toExponential(2));
    }
}

例如 3:下面的示例代码没有编译错误,但会出现运行时错误,因为 TypeScript
只会将类型缩小到string受保护的块中而不是之后,因此foo.toExponential不会产生编译错误(TypeScript
认为它不是string类型)。但是,在运行时,string没有该toExponential方法,因此会出现运行时错误。

function example(foo: any){
    if(isString(foo)){
        console.log("it is a string" + foo);
        console.log(foo.length);
    }
    console.log(foo.toExponential(2));
}

例 4:如果我们不使用test is string(类型谓词),TypeScript
不会缩小受保护块中的类型,下面的示例代码不会出现编译错误,但会出现运行时错误。

function isString(test: any): boolean{
    return typeof test === "string";
}
function example(foo: any){
    if(isString(foo)){
        console.log("it is a string" + foo);
        console.log(foo.length);
        console.log(foo.toExponential(2));
    }
}

结论是test is string(类型谓词)在编译时用于告诉开发人员代码将有机会出现运行时错误。对于
javascript,开发人员不会知道编译时的错误。这就是使用 TypeScript 的优势。

2022-06-06