0
"typescript": "2.7.2"

How/WHY this code worked without any IDE error or --aot compile error on Angular 6 project?

private func1() {
    const b: B = new B();
    b.name = 'jack';
    this.func2(b);
}

private func2(a: A) {
    console.log(a.name); //prints jack
}

-

export class A {
    public name: string;
}

export class B {
    public name: string;
    public surname: string;
}
7
  • The two classes are the same, I don't see any difference in parameters type ... Commented May 15, 2018 at 9:58
  • @trichetriche I edited the question. the classes are not exactly same but it works. On the other hand if they were exactly same and have different names can it works though? Commented May 15, 2018 at 10:01
  • Adding a property won't create an error on already working classes ... This will work too without issues. What do you mean with different names ? The value of the name property ? I really don't see where you're going, maybe you should state what is bothering you ; Commented May 15, 2018 at 10:03
  • 1
    I see. In Javascript classes don't exist, and variables aren't typed. This means that as long as the classes have the required properties, it will work. Try renaming one name to surname, and you will see your IDE throws an error. And if you look at it, you will see that it says that objects don't match anymore (not classes, not values, not types, but plain objects) Commented May 15, 2018 at 10:09
  • 1
    I guess they only throw errors when Javascript errors will pop, since Typescript will never be read as Typescript. Maybe you can set your linter to detect this kind of issue, but I don't know how ... Commented May 15, 2018 at 10:18

1 Answer 1

2

TypeScript uses a structural type system. This means that types are compared by their contents. As opposed to most other everyday languages, who use nominal type systems where types are compared by their name. Therefore, in TypeScript, your type B can be used where type A is expected because the "shape" of type B exactly matches the "shape" needed for type A – all the members of type A are present in type B and their own types match.

This approach was selected by the TypeScript language designers because it fits well with existing JavaScript idioms, such as using plain object literals received via AJAX without coercing them into a named type. This design choice causes some friction in scenarios when nominal type system elements would be convenient (e.g. identifier types like ProductId and OrderId should be incompatible).

Relevant reading:

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.