V
V
Vitaly2016-06-22 13:54:56
JavaScript
Vitaly, 2016-06-22 13:54:56

Why does typescript compiler swear?

All the best!
So I decided to get acquainted with Angular 2 (+ typescript with es6 at the same time).
Just digging in for now... here is my code snippet :

export class AppComponent {
   title = 'hero';
    hero: Hero = {
      id: 1,
      name: 'Wind'
    }

 }

I start the project with commands:
tsc && concurrently \"tsc -w\" \"lite-server\"

Everything is building, everything is OK ...
in the process I changed the code to:
export class AppComponent {
  constructor (){
    this.sommm = 'from this some'
  }
    title = 'hero';
    hero: Hero = {
      id: 1,
      name: 'Wind'
    }
 }

i.e. added
constructor (){
    this.sommm = 'from this some'
  }

everything also works, and the sommm variable in html as {{somme}} is displayed normally. But as soon as I restart the server, the compilation fails again, says:

tsc && concurrently "tsc -w" "lite-server"
app/app.component.ts(15,10): error TS2339: Property 'sommm' does not exist on type 'AppComponent'.
npm ERR! Darwin 15.5.0
npm ERR! argv "/Users/scorpio/.nvm/versions/node/v5.1.0/bin/node" "/Users/scorpio/.nvm/versions/node/v5.1.0/bin/npm" "start"
npm ERR! node v5.1.0
npm ERR! npm v3.3.12
npm ERR! code ELIFECYCLE
npm ERR! [email protected] start: `tsc && concurrently "tsc -w" "lite-server" `
npm ERR! Exit status 2
npm ERR!
npm ERR! Failed at the [email protected] start script 'tsc && concurrently "tsc -w" "lite-server" '.
npm ERR! Make sure you have the latest version of node.js and npm installed.
npm ERR! If you do, this is most likely a problem with the angular2-quickstart package,
npm ERR! not with npm itself.
npm ERR! Tell the author that this fails on your system:
npm ERR! tsc && concurrently "tsc -w" "lite-server"
npm ERR! You can get their info via:
npm ERR! npm owner ls angular2-quickstart
npm ERR! There is likely additional logging output above.
npm ERR! Please include the following file with any support request:
npm ERR! /Users/scorpio/Documents/git/io2/heroes/npm-debug.log

Please explain to me what is happening and why. Thank you for your understanding :)
PS
Maybe it's because the constructor is run when it is created with new ?

Answer the question

In order to leave comments, you need to log in

3 answer(s)
B
bromzh, 2016-06-22
@Scorpiored88

I’ll correct Evgeny a little, it’s enough to declare the desired field in the class, the type can be omitted:

export class AppComponent {
    sommm; // Можно и без типа, зависит от настройки компилятора
    title = 'hero';
    hero: Hero = {
      id: 1,
      name: 'Wind'
    }
    constructor (){
      this.sommm = 'from this some'
    }    
 }

Or you can also add a modifier to the constructor argument:
export class AppComponent {
    // В Angular 2 так можно делать в классах, 
    // которые не являются компонентами/директивами/сервисами/пайпами и т.п.
    constructor (public sommm: string = 'from this some') {}   
 }
// Это аналогично такому:
export class AppComponent {
    sommm: string;
    constructor (sommm: string = 'from this some') {
        this.sommm = sommm;
    }    
 }

But types are still better to specify.
UPD0 . In TypeScript, if a variable has a type other than any, you can't dynamically add fields to it. When an instance of the class is created (operator new), a special method named 'constructor' is called. You are trying to write in the constructor in the sommm field. The TypeScript compiler works up to runtime and determines the types based on the class declaration. In this case, the AppComponent type has 2 fields (title, hero). So from his point of view, the AppComponent type does not have a sommm field, which is why he swears.
Sometimes, apparently due to the peculiarities of live servers, it happens that even though the compiler swears at a type mismatch, the code starts up and works, because from the point of view of JS, everything looks right.
UPD 1. Although I gave an example where I did not specify the types of variables, you should (almost) never do this. To protect yourself from writing such code, you can add the "noImplicitAny" compiler option . Without it, the following code will compile without errors:
let a;
function foo(bar) {}
class Bar {
  foo;
  private bar;
}

With this option enabled, the compiler will generate errors where variables, function and method arguments, or class fields are declared without types.
You should always try to specify the type of variables. If one type doesn't fit, you can try making the function/method/class generic . If the type is unknown, then you can put any. But usually this rarely happens, because usually you know what type is expected (I have almost no variables with type any in my projects).
UPD2 . I gave an example where a modifier is specified in the constructor. This is a special syntax in Typescript that allows you to reduce the amount of repetitive code.
However, there is an important point: dependency injection in components/directives/services/etc. in the second angular goes through the constructor. Moreover, in the typescript version, the framework by default extracts information about the type of the constructor argument and tries to inject the necessary dependency on this type. Therefore, only injectable dependencies should be in constructors.
UPD3 . If you write in Angular, then you should study the styleguide and try to follow it. Plus, it's good to attach tslint to the project.

E
Eugene, 2016-06-22
@AppFA

Try declaring the type of this variable before the constructor
. Your error says that there is no such property in the class:
"Property 'sommm' does not exist on type 'AppComponent'."

sommm: string;

constructor() {
    this.sommm = 'from this some';
}

_
_ _, 2016-06-22
@AMar4enko

public somm;

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question