简体   繁体   中英

Should the declaration order affect TypeScript type deduction?

It seems that TypeScript's translator somehow relies on the order of declaration, at least in case of overloaded functions.

Lets say we have classes for 2- and 3-dimensional vectors:

class Vector2 {
  public get x() : number
  public get y() : number
}
class Vector3 {
  public get x() : number
  public get y() : number
  public get z() : number
}

And we have an overloaded function which accepts either Vector2 or Vector3 :

function add(a : Vector2, b : number) : Vector2;
function add(a : Vector3, b : number) : Vector3;

Depending on which signature of add() goes first - with Vector2 or Vector3 result - the compiler may deduce different type of the result, even if we pass as a parameter exactly Vector3 . For instance, in case of the same order as mentioned above, the following code:

const r = add(new Vector3, 5)

Will return Vector2 instead of Vector3 . Because of this, if we put constraints on the possible type of r as Vector3 :

const r : Vector3 = add(new Vector3, 5)

the code will not compile.

Is this should to be so? Because for me it looks like an error in the translator.

This is the expected behaviour of Typescript: when you call an overloaded function, the compiler chooses the first overload signature which is compatible at the call-site, not the most-specific signature. From the docs :

TypeScript chooses the first matching overload when resolving function calls. When an earlier overload is “more general” than a later one, the later one is effectively hidden and cannot be called.

Since your Vector3 is a structural subtype of your Vector2 , the Vector3 overload signature is more specific so you should write that one before the Vector2 overload signature.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM