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

Dre*_*rew 59 typescript

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

export function foo(arg: string): arg is MyType {
    return ...
}
Run Code Online (Sandbox Code Playgroud)

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

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

小智 69

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”);
Run Code Online (Sandbox Code Playgroud)

在上面的格式中使用类型谓词"test is string"(而不是仅仅使用boolean作为返回类型),在调用isString()之后,如果函数返回true,TypeScript会将类型缩小为字符串,在任何由a保护的块中打电话给这个功能. 编译器会认为foo是以下保护块中的字符串(并且仅在以下保护块中)

{
    console.log(“it is a string” + foo);
    console.log(foo.length); // string function
}
Run Code Online (Sandbox Code Playgroud)

类型谓词仅用于编译时.结果.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));
    }
}
Run Code Online (Sandbox Code Playgroud)

例如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));
}
Run Code Online (Sandbox Code Playgroud)

例如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));
    }
}
Run Code Online (Sandbox Code Playgroud)

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

  • 我感到惊讶的是,它有如此多的赞誉,而且没有人使用智能引号对示例发表任何评论... (3认同)

Bru*_*der 7

我知道的唯一用法就是您的示例之一:arg is MyType在用户定义的Type Guard中指定“ type predicate”()

请参见本参考中的用户定义类型防护

这是另一个参考

  • @benjaminz 我不明白布尔值如何处理它。Typescript 需要知道向其中传递对象的函数的功能类似于类型保护。如果它只返回类型 true 或 false,Typescript 如何知道它确实是类型保护,而不仅仅是某个在对象为真时返回 true 的任意函数。它如何知道缩小对象的类型?其次,它如何知道将对象的类型缩小到什么类型?如果参数是三种类型之一怎么办?它需要知道“true”对应于特定类型。 (3认同)
  • 我也在文档中看到了这一点,多么奇怪的设计决定,这种情况完全可以通过返回类型 `boolean` 来处理,对吗? (2认同)
  • @benjaminz这也许可以证明这是SO本身的问题,但我可以向您展示一个简单的例子说明它们的不同之处。is关键字实际上是在强制转换类型,可以在以后的代码中捕获类型错误。有关更多信息,请参见[此示例](https://goo.by/WAlvg)。 (2认同)