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.

enter image description here

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:

  1. 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; 
  2. 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

Popular posts from this blog

networking - Vagrant-provisioned VirtualBox VM is not reachable from Ubuntu host -

c# - ASP.NET Core - There is already an object named 'AspNetRoles' in the database -

ruby on rails - ArgumentError: Missing host to link to! Please provide the :host parameter, set default_url_options[:host], or set :only_path to true -