farwayer
farwayer

Reputation: 4122

Typing for optional callable decorator in Typescript

I am writing typescript typings for some js library. I need to declare optionally callable decorator:

@model
class User {}

@model()
class User {}

@model('User')
class User {}

I tried to use ClassDecorator from lib.es6.d.ts but with no luck:

// works
export const model: ClassDecorator;

// error TS1238: Unable to resolve signature of class decorator when called as an expression. Cannot invoke an expression whose type lacks a call signature. Type 'ClassDecorator | CallableModelDecorator' has no compatible call signatures
type CallableModelDecorator = (name?: string) => ClassDecorator;
export const model: ClassDecorator | CallableModelDecorator;

Of course I can make manual typing as workaround:

export function model<TFunction extends Function>(target: TFunction): TFunction | void;
export function model(name?: string):
  <TFunction extends Function>(target: TFunction) => TFunction | void;

But how can I reuse existing ClassDecorator type in this case?

Upvotes: 0

Views: 437

Answers (1)

Titian Cernicova-Dragomir
Titian Cernicova-Dragomir

Reputation: 249486

The problem is you are using an union type, variables of these types only have the common members of both types, so in this case since only one of the types is callable, the union will not be callable

You are looking for an intersection type, that will have member of both of type types

export const model: ClassDecorator & CallableModelDecorator;

Upvotes: 2

Related Questions