什么是'is`关键字在打字稿中做什么?

时间:2016-10-17 08:06:50

标签: typescript

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

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

我无法在文档或Google中搜索is,这是一个非常常见的词,并且基本上显示在每个页面上。

该关键字在该上下文中的作用是什么?

2 个答案:

答案 0 :(得分:49)

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),在调用isString()之后,如果函数返回true, TypeScript会将类型缩小为字符串在通过调用该函数守卫的任何区块中。 编译器会认为foo是以下保护块中的字符串(并且仅在下面的保护块中)

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

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

我将在下面的四个例子中说明差异。

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

例如:2 下面的示例代码将有编译错误(以及运行时错误),因为TypeScript已将类型缩小为字符串并检查toExponential不属于字符串方法。

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

E.g。 3: 下面的示例代码没有编译错误,但会有运行时错误,因为TypeScript只会将类型缩小为块中的字符串,而不是之后,因此foo.toExponential不会创建编译错误(TypeScript认为它不是字符串类型)。但是,在运行时,字符串没有toExponential方法,因此它将有运行时错误。

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

E.g。 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的优势。

答案 1 :(得分:6)

我所知道的唯一用途就是你的例子之一:在用户定义的Type Guard中指定“类型谓词”(<?php $array1 = array ( "0" => Array ( "field1" => "A", "field2" => "100", "field3" => "20" ), "1" => Array ( "field1" => "B", "field2" => "100", "field3" => "30" ), "2" => Array ( "field1" => "C", "field2" => "100", "field3" => "30" ) ); $array2 = array ( "0" => Array ( "field1b" => "A", "field2b" => "500", "field3b" => "0" ), "1" => Array ( "field1b" => "B", "field2b" => "300", "field3b" => "10" ) ); $new_array1 = []; foreach ($array1 as $object1) { $new_array1[$object1['field1']] = $object1; } $new_array2 = []; foreach ($array2 as $key => $object2) { $new_array2[$object2['field1b']] = $object2; } $new_array = []; foreach($new_array1 as $key => $val) { $new_array[$key]['field1'] = $val['field1']; $new_array[$key]['field2'] = $val['field2']; $new_array[$key]['field3'] = $val['field3']; if (array_key_exists($key,$new_array2))//Check if the key is exists in an array { $new_array[$key]['field2b'] = $new_array2[$key]['field2b']; $new_array[$key]['field3b'] = $new_array2[$key]['field3b']; } } print_r($new_array);

请参阅此reference

中的用户定义类型警卫

这是另一个reference