typescript - how do I properly write function signature to accept union-typed parameter? -


i trying provide api function accepts parameter can of type or b. using interfaces type parameters. type not share single member. attempts lead compiler complaining property x not present on type x.

export interface mytypea {   prop1: string;   prop2: boolean; }  export interface mytypeb {   prop3: number;   prop4: string; }  dosomething(param1: string, param2: mytypea | mytypeb){   switch(param1){     case 'a':     case 'b': {       const cf = this.resolver.resolvecomponentfactory(myclassacomponent);       const component = this.wrap.createcomponent(cf);       component.instance.prop1 = param2.prop1;       component.instance.prop2 = param2.prop2;       break;     }     case 'c': {       const cf = this.resolver.resolvecomponentfactory(myclassbcomponent);       const component = this.wrap.createcomponent(cf);       component.instance.prop3 = param2.prop3;       break;     }    } } 

i not sure can done interfaces, assume might rather have use type, don't know how.

i see 3 possible solutions:

i go tagged unions if makes sense combine param1 , param2. otherwise use user defined type guards.

👉 cast each single usage of param2:

too verbose in opinion if have use many times, straight forward solution:

...  component.instance.prop1 = (param2 mytypea).prop1; component.instance.prop2 = (param2 mytypea).prop2;  ... 

this solution not generate additional code (the cast completelly removed generated code).

👉 use tagged unions (aka discriminated unions or algebraic data types):

you can combine param1 , param2 , convert custom types tagged unions:

export interface mytypea {   param1: 'a' | 'b';   prop1: string;   prop2: boolean; }  export interface mytypeb {   param1: 'c';   prop3: number;   prop4: string; }  dosomething(param2: mytypea | mytypeb) {   switch(param2.param1) {     case 'a':     case 'b': {       // compiler knows param2 of type mytypea, because param1       // property either 'a' or 'b'.        const cf = this.resolver.resolvecomponentfactory(myclassacomponent);       const component = this.wrap.createcomponent(cf);        component.instance.prop1 = param2.prop1;       component.instance.prop2 = param2.prop2;        break;     }      case 'c': {       // compiler knows param2 of type mytypeb, because param1       // property 'c'.        const cf = this.resolver.resolvecomponentfactory(myclassbcomponent);       const component = this.wrap.createcomponent(cf);        component.instance.prop3 = param2.prop3;        break;     }   } } 

this solution not generate additional code (the interfaces, including tagged param, not present in generated code).

👉 use user defined type guards:

you can use user defined type guards narrow down type of param2:

export interface mytypea {   prop1: string;   prop2: boolean; }  export interface mytypeb {   prop3: number;   prop4: string; }  function isa(arg: any): arg mytypea {     return arg.hasownproperty('prop1'); }  function isb(arg: any): arg mytypeb {     return arg.hasownproperty('prop3'); }  dosomething(param1: string, param2: mytypea | mytypeb) {   switch(param1) {     case 'a':     case 'b': {       if (!isa(param2)) return;        // compiler knows param2 of type mytypea:        const cf = this.resolver.resolvecomponentfactory(myclassacomponent);       const component = this.wrap.createcomponent(cf);        component.instance.prop1 = param2.prop1;       component.instance.prop2 = param2.prop2;        break;     }      case 'c': {       if (!isb(param2)) return;        // compiler knows param2 of type mytypeb:        const cf = this.resolver.resolvecomponentfactory(myclassbcomponent);       const component = this.wrap.createcomponent(cf);        component.instance.prop3 = param2.prop3;        break;     }   } } 

note solution generate additional code, isa , isb functions, calls them, included in generated code.


Comments

Popular posts from this blog

node.js - Node js - Trying to send POST request, but it is not loading javascript content -

javascript - Replicate keyboard event with html button -

javascript - Web audio api 5.1 surround example not working in firefox -