polymorphism - TypeScript declaration for polymorphic decorator -
i’m in process of writing ambient declaration react-tracking. exposes track
decorator can used on both classes and methods.
a simplified example taken docs:
import track 'react-tracking' @track({ page: 'foopage' }) export default class foopage extends react.component { @track({ action: 'click' }) handleclick = () => { // ... } }
in ambient declaration file expected able following , have typescript choose right overload:
declare function track(trackinginfo?: any, options?: any): <t>(component: t) => t declare function track(trackinginfo?: any, options?: any): export default track
while works component classes, fails methods following error:
[ts] unable resolve signature of method decorator when called expression.
looking @ typing ts chooses application of decorator indicates it’s not falling signature should match anything, instead component class one.
is possible type polymorphic decorator @ all? and, if so, doing wrong?
update: here’s reduced simplified example.
the first 1 monomorphic , works expected:
function trackclass(trackinginfo?: any, options?: any): classdecorator { return null } function trackmethod(trackinginfo?: any, options?: any): methoddecorator { return null } @trackclass({}) class foo { @trackmethod({}) somemethod() {} }
this second example polymorphic , fails both:
function track(trackinginfo?: any, options?: any): classdecorator | methoddecorator { return null } @track({}) class bar { @track({}) somemethod() {} }
typescript's lib.d.ts
has classdecorator
, methoddecorator
type:
declare type classdecorator = <tfunction extends function>(target: tfunction) => tfunction | void; declare type methoddecorator = <t>(target: object, propertykey: string | symbol, descriptor: typedpropertydescriptor<t>) => typedpropertydescriptor<t> | void;
you can either 1 of 2 things:
create type has overloads compatible both:
interface trackdecorator { // class decorator overload <tfunction extends function>(target: tfunction): tfunction; // property decorator overload <t>(target: object, propertykey: string | symbol, descriptor: typedpropertydescriptor<t>): typedpropertydescriptor<t>; } export default function track(trackingdata?: object): trackdecorator;
derive type combine overloads appropriately.
interface trackdecorator extends classdecorator, methoddecorator { } export default function track(trackingdata?: object): trackdecorator;
the former allows more specific, latter tie whatever version typescript has in mind decorators (in other words, if spec changes, implied react-tracking
supports either version).
Comments
Post a Comment