Takeshi Tokugawa YD
Takeshi Tokugawa YD

Reputation: 923

The `ClassDecorator` type defined in `tc39/proposal-decorators` is not applicable without TypeScript errors

I got the error

TS1270: Decorator function return type 'void | Function' is not assignable to type 'void | typeof ReactiveStateExperimentalSample'.

  Type 'Function' is not assignable to type 'void | typeof ReactiveStateExperimentalSample'.

    Type 'Function' is not assignable to type 'typeof ReactiveStateExperimentalSample'.        Type 'Function' provides no match for the signature 'new (): ReactiveStateExperimentalSample'.

when tried to apply the decorator

const VueComponentOptions: (
  value: Function,
  context: {
    kind: "class";
    name: string | undefined;
    addInitializer(initializer: () => void): void;
  }
) => Function | void = (
  value: Function, context: ClassDecoratorContext
): Function | void => {

  const vueOptions: ComponentOptions = {
    methods: {},
    computed: {}
  };

  return defineComponent(vueOptions);

};

to class

@VueComponentOptions
export default class ReactiveStateExperimentalSample {

}

According tc39/proposal-decorators, the signature of class decorator is

type ClassDecorator = (value: Function, context: {
  kind: "class";
  name: string | undefined;
  addInitializer(initializer: () => void): void;
}) => Function | void;

There is no such type in TypeScript 5 (more exactly, in typescript/lib/lib.decorators.d.ts). There is such type in typescript/lib/lib.decorators.legacy.d.ts but legacy is legacy.

Am I doing something wrong or it is just immature API? TypeScript 5 is not the beta anymore, thus "experimental decorators" is not experimental anymore.

Upvotes: 1

Views: 766

Answers (1)

Dimava
Dimava

Reputation: 10841

TS decorators are not fully TC39-compatible yet

// logs [class X{}]
@((...a) => console.log(a))
class X {}

https://www.typescriptlang.org/play?experimentalDecorators=true&ts=5.1.0-dev.20230402#code/PTAEBsHsHMGdQNoGNwENbwBoG8C+BdAKAAEAKUgOitQEpQBeAPlCUgDtZJwBTCqaUrRqEU6LKDyEgA

So meanwhile your decorators should follow the current typings

// lib.es5.d.ts
declare type ClassDecorator = <TFunction extends Function>(target: TFunction) => TFunction | void;
declare type PropertyDecorator = (target: Object, propertyKey: string | symbol) => void;
declare type MethodDecorator = <T>(target: Object, propertyKey: string | symbol, descriptor: TypedPropertyDescriptor<T>) => TypedPropertyDescriptor<T> | void;
declare type ParameterDecorator = (target: Object, propertyKey: string | symbol, parameterIndex: number) => void;

Upvotes: 2

Related Questions