TypeError i TypeScript-genererad JavaScript


Varför genererar JavaScript-koden som skapas av följande TypeScript-kod ett TypeError när den körs?

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

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

new Foo();

Jag kompilerar koden med --strict-alternativet, så jag skulle förvänta mig att tilldelningen till en oinitierad variabel skulle upptäckas, men det gör den inte.

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)

Jag använder TypeScript 2.5.3.

Svar #1

Jag är mer av en Javascript-purist, så jag är ingen expert på TypeScript.

Men jag har precis gått ut till lekplatsen, nedan är vad din kod kompileras till. Dessutom har du this.foo["bar"], och TypeScript skulle inte klaga om du hade this.foo["bar-the-third"], jag antar att du ville ha this.foo.bar.

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

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

new Foo();

Från att titta på outputen försöker Typescript vid inget tillfälle generera objektet, det verkar som om detta skulle lämnas till dig. Med andra ord: Typescript kontrollerar bara typen, genererar inte automatiskt koden åt dig. Så från att titta på detta är den definitionen bara för att kontrollera typen.

Men om du faktiskt skapar objektet verkar Typescript göra kontrollen.

t.ex.

public foo: {
  bar: number
} = {bar: 123};

//or

this.foo = {bar: 123};

Svar #2

Som en lösning, om foo kan vara undefined, skulle du kunna deklarera det så här:

public foo: {
  bar: number
} | undefined;

... då uppstår ett fel vid kompilering (med alternativet --strictNullCheck).

Se även länken till GitHub-ärendet som delades av @Aleksey L.