angular - typescript 中的运行时类型安全

标签 angular typescript

我试图更好地理解 Typescript 中的类型安全,并遇到了我有这个功能的场景:

function test(x: number){
    console.log(typeof x);
}

如果我这样调用这个方法 - test('1')它会引发编译时错误,但如果我将其更改为以下内容,则它可以正常工作:
let y: any = '1';
test(y);
//works fine
//Outputs "string"

据我了解,将 'x' 声明为数字仅在编译时有效,并且 Typescript 仅强制执行编译时类型安全而不是运行时。所以,我想知道我是否理解正确或遗漏了什么,还有哪些不同的方法可以确保运行时类型安全?

最佳答案

TypeScript 是两种合并的语言:

  • 类型级语言
  • 值(value)级语言

  • 第一个在所有类型注释中都是可见的,它是纯 JavaScript 中不存在的语法。每个类型注释和保留字,如 type, interface, enum, as, in是类型级语言的一部分。 TS 在编译过程中首先要做的是检查类型级语言的语法和语法的正确性以及值级语言的注释的正确性。

    第二个是值级语言,完全正确的JS语法。它还具有 ECMAScript 提案第 3 阶段的大部分功能。

    第一部分被完全删除(Enum 除外,它在运行时具有表示),第二部分保留在运行时中。

    回到关于安全的问题,是的 TypeScript 在编写代码的过程中确保安全。您定义契约(Contract),编写契约(Contract)的转换,并且 TS 正在检查与契约(Contract)注释相关的代码的正确性。它消除了一大堆错误,如拼写错误,或使用空/ undefined object 的方法和属性,它还在程序流程中给出了数据的可见定义。

    但是,它不保护运行时。所有类型注解都只是假设,如果我们定义API具有端点响应的这样那样的结构,那么TS会保证代码会遵循这种结构,但是如果在运行时,结构会有所不同,程序自然会失败,因为契约(Contract)不等于数据。

    回到你的例子
    function test(x: number){
        console.log(typeof x);
    }
    

    定义函数 test作为采用 number 的函数作为论点,你说的没有什么不同,然后 number将传递给函数。所以上面的实现确实是一个常量,如typeof x将永远返回 number ,因为这正是注释所说的。
    // below is equal to your implementation, as number has one specific type
    // caution is equal for TS, not for the runtime!
    function test() {
      return console.log('number')
    }
    

    如果函数在输入方面是多态的,那么输入应该被这样注释。可能会发生您不知道可以获得什么输入的情况,然后您可以实现结构检查。它的正确名称是 - type guard .考虑下面的例子
    function test(x: unknown) {
      if (typeof x === 'number') {
        return x * 2; // return number
      }
      if (typeof x === 'string') {
        return x + '- I am string'; // return number
      }
    
      if (typeof x === 'object') {
        return x; // return object;
      }
    
      return null; // for others return null
    }
    

    现在功能test将输出推断为联合 string | number | object | null .通过使用控制流和条件,TS 能够理解函数返回的内容。

    每次您的代码处理一些多态类型时,您都可以使用类型保护来准确指定您正在使用的类型。检查是由结构体完成的(因为运行时只存在结构体,type只在写代码时对结构体进行注解),所以可以检查typeof , instanceof或者对象是否具有特定的键或值。

    非常重要的事情要记住 - 类型 是一些现有运行时结构的标签。标签/类型在运行时不存在,但结构存在。这就是 TS 能够理解类型保护的原因,因为每种类型都指代某种结构。

    关于angular - typescript 中的运行时类型安全,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59135732/

    相关文章:

    typescript - 导入任何 .d.ts 都会导致运行时错误

    java - 将 jsp 页面移至 Angular 7

    angular - 如何在 Ag-Grid 中隐藏排序顺序指示器?

    angular - 当 Font Awesome 带宽使用量超过我本月计划允许的 npm 带宽时,会发生什么?

    使用 Jasmine 的 TypeScript 中的 AngularJS 单元测试未运行

    typescript - VSCode 调试器和 typescript : Step Over/Into goes to JS file

    TypeScript 泛型 "extends"约束 : Is there a nullable constraint?

    Angular 7 库 - 如何在不将依赖项添加到主应用程序的情况下捆绑依赖项

    html - ngFor 循环中的换行符

    javascript - 当互联网关闭时启用离线功能