There is a function called add, which declares that adding two values of type A will return type A, and adding two values of type B will return type B. test.d.ts
But in actual use, the result of adding Bs together is A. Why?
Minimal entire code to reproduce the problem test.ts
testlib.d.ts
testlib.js
explanation
- TypeScript is a structural type system, not a nominal type system
- So types with the same structure are the same type
- A and B are the same type because they have the same structure
- So the rule of
export function add(x: A, y: A): A;
that appeared earlier is used, and the return value is A
A and B are not distinguished, so adding A and B does not result in an error. :
let ab = add(new A(), new B()); // No error
solution testlib.d.ts
Now A and B are distinguished as types because they have different structures.
In this example, we chose to “add a member that is not used” because the situation was one in which we wanted to distinguish between the two classes.
This method cannot be used in cases where you want to distinguish between string types because you cannot add members.
Another way is to create an INTERSECTION with ENUM. In this case, you can use as FooId
to set the string type to the FooId type.
ts
relevance
This page is auto-translated from /nishio/名前的型と構造的型の勘違いによる実話 using DeepL. If you looks something interesting but the auto-translated English is not good enough to understand it, feel free to let me know at @nishio_en. I’m very happy to spread my thought to non-Japanese readers.