typescript - Compatible types in functions -


let have code:

class myevent {     timestamp:number; } class aevent extends myevent{     x:number;     y:number;    } class bevent extends myevent{     key:string;  } var fn:(event:myevent)=>void; function ae(event:aevent){     let x = event.x; //ok, bevent hasn't 'x' property.  } fn = ae; fn(new bevent()); 

typescript doesn't inform error. typescript valid code. have tried in typescript playground. (1.8 version)

how enforce typescript forbid it?

for example, in c++

class base {     public:         int timestamp; };  class b: public base {     public:         char key;  }; class a: public base {     public:         int x;         int y; };   void fa(a *ptr) {}  void (*fn)(base *ptr);   int main() {     *a = new a();     b *b = new b();      fn = fa; //error: invalid conversion 'void (*)(a*)' 'void (*)(base*)'      fn(b); } 

the function parameters bivariant allow common javascript patterns if runtime error can occur in rare case.

according type compatibility handbook :

when comparing types of function parameters, assignment succeeds if either source parameter assignable target parameter, or vice versa. unsound because caller might end being given function takes more specialized type, invokes function less specialized type. in practice, sort of error rare, , allowing enables many common javascript patterns.

why function parameters bivariant?

in summary, in typescript type system, question of whether more-specific-type-accepting function should assignable function accepting less-specific type provides prerequisite answer whether array of more specific type should assignable array of less specific type. having latter not case not acceptable type system in vast majority of cases, have take correctness trade-off specific case of function argument types.


Comments