【问题标题】:TypeError in TypeScript Generated JavaScriptTypeScript 生成的 JavaScript 中的 TypeError
【发布时间】:2018-03-14 12:15:09
【问题描述】:

为什么下面的 TypeScript 代码生成的 JavaScript 在执行时会生成一个TypeError

class Foo {
  public foo: {
    bar: number
  };

  constructor() {
    this.foo["bar"] = 123;
  }
}

new Foo();

我正在使用 --strict 选项编译代码,所以我希望对未初始化变量的赋值会被捕获,但它不会。

C:\Users\Simon\test.js:4
        this.foo["bar"] = 123;
                        ^

TypeError: Cannot set property 'bar' of undefined
    at new Foo (C:\Users\Simon\test.js:4:25)
    at Object.<anonymous> (C:\Users\Simon\test.js:8:1)
    at Module._compile (module.js:570:32)
    at Object.Module._extensions..js (module.js:579:10)
    at Module.load (module.js:487:32)
    at tryModuleLoad (module.js:446:12)
    at Function.Module._load (module.js:438:3)
    at Module.runMain (module.js:604:10)
    at run (bootstrap_node.js:389:7)
    at startup (bootstrap_node.js:149:9)

我使用的是 TypeScript 2.5.3。

【问题讨论】:

  • 如果您想在编译时遇到错误 - 目前是不可能的。 Related issue

标签: javascript typescript undefined typeerror


【解决方案1】:

作为一种解决方法,如果 foo 可以是 undefined,您可以声明:

public foo: {
  bar: number
} | undefined;

...那么编译时会发生错误(使用选项--strictNullCheck)。

另请参阅@Aleksey L 分享的link to the GitHub issue

【讨论】:

    【解决方案2】:

    我更喜欢 Javascript 纯粹主义者,所以不是 TypeScript 专家。

    但我刚刚去了操场,下面是您的代码编译的内容。你也有this.foo["bar"],如果你有this.foo["bar-the-third"],打字稿不会抱怨,我假设你想要this.foo.bar

    class Foo {
      public foo: {
        bar: number
      };
    
      constructor() {
        this.foo.bar = 123;
      }
    }
    
    new Foo();
    

    从查看输出来看,Typescript 绝不会尝试生成对象,看来这将留给您。 IOW:Typescript 只是检查类型,而不是自动为您生成代码。所以从这个来看,这个定义只是为了检查类型。

    但如果您确实创建了对象,Typescript 似乎会进行检查。

    例如。

    public foo: {
      bar: number
    } = {bar: 123};
    
    //or
    
    this.foo = {bar: 123};
    

    【讨论】:

    • 是的,我不希望 TypeScript 为我初始化对象,而是不让我分配给未定义的变量。在我的实际项目中这让我感到困惑的原因是因为某些字段的值在编译时是未知的,而其他字段的值依赖于其他字段。
    • 是的,我知道你是从哪里来的。不过,开发人员可能很难捕捉到这一点,因为它需要知道foo 没有被分配到其他地方,例如。继承、另一个函数、绑定等。即使获取 TypeScript 输出并将其放入严格的 ESLint 也不能​​解决这个问题。
    • 正如其他人指出的那样,开发人员似乎正在努力,所以仍有希望。我确信开发人员有合理的理由让它没有被捕获,但其他静态类型语言似乎能够捕获这类错误,这就是它让我感到惊讶的原因。我的猜测是 TypeScript 类型系统的工作方式使得这个问题比例如像 Java 这样的语言。
    【解决方案3】:

    您正在尝试为尚未初始化的 this.foo 上的键 bar 设置值。初始化它就在这个this.foo = { bar: 123};

    【讨论】:

    • 我知道。我在问为什么我在启用所有严格选项的情况下编译代码时 TypeScript 没有捕捉到这个非常基本的错误。
    • 抱歉,我刚刚注意到您在问题中明确提到了这一点。
    猜你喜欢
    • 2019-01-11
    • 2016-09-21
    • 1970-01-01
    • 2016-08-11
    • 1970-01-01
    • 1970-01-01
    • 2013-08-20
    • 1970-01-01
    相关资源
    最近更新 更多