Simon Morgan
Simon Morgan

Reputation: 2248

TypeError in TypeScript Generated JavaScript

Why does the JavaScript generated by the following TypeScript code generate a TypeError when executed?

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

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

new Foo();

I'm compiling the code with the --strict option so I'd expect the assignment to an uninitialised variable to get caught but it doesn't.

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)

I'm using TypeScript 2.5.3.

Upvotes: 2

Views: 113

Answers (3)

Paleo
Paleo

Reputation: 23772

As a workaround, if foo can be undefined, you could declare that:

public foo: {
  bar: number
} | undefined;

... then an error will occur at compile time (with the option --strictNullCheck).

See also the link to the GitHub issue shared by @Aleksey L.

Upvotes: 1

Keith
Keith

Reputation: 24241

I'm more of a Javascript purist, so no expert on TypeScript.

But I've just gone on to the playground, below is what your code compiles too. Also you have this.foo["bar"], and typescript wouldn't complain if you had this.foo["bar-the-third"], I'm assuming you wanted this.foo.bar.

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

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

new Foo();

From looking at the output, at no point does Typescript attempt to generate the object, it appears this would be left to you.. IOW: Typescript is just checking the type, not automatically generating the code for you. So from looking at this, that definition is just for checking type.

But if you do create the object, Typescript seem to do the check.

eg.

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

//or

this.foo = {bar: 123};

Upvotes: 1

Andrzej Smyk
Andrzej Smyk

Reputation: 1724

You are trying to set value to key bar on this.foo which is not initialised yet. Initialize it lie this this.foo = { bar: 123};

Upvotes: 0

Related Questions