Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

TypeScript decorator reports "Unable to resolve signature of class decorator when called as an expression"

Tags:

typescript

@xxx("xxx") class A{     msg:string     constructor(msg:string) {         this.msg = msg     }     print() {         console.log(this.msg)     } }  function xxx(arg:string) {     function f(target) {         function ff(msg: string) {             return new target(arg + ":" + msg)         }         return ff     }     return f }  let a = new A("hellow") a.print() 

When compile, it reports:

decorator.ts(1,1): error TS1238: Unable to resolve signature of class decorator when called as an expression. Type '(msg: string) => any' is not assignable to type 'void'.

But the genrated js executed well. I don't know why report error.

like image 898
cloud Avatar asked Apr 06 '16 09:04

cloud


People also ask

Are decorators still experimental in TypeScript?

Decorators are a stage 2 proposal for JavaScript and are available as an experimental feature of TypeScript. NOTE Decorators are an experimental feature that may change in future releases.

What is class decorator in TypeScript?

Typescript Class Decorators Definition: The class decorator is applied to the constructor of the class and can be used to observe, modify, or replace a class definition.(reference)

How do you use a decorator in TypeScript?

In TypeScript, you can create decorators using the special syntax @expression , where expression is a function that will be called automatically during runtime with details about the target of the decorator. The target of a decorator depends on where you add them.

What are JavaScript decorators?

JavaScript decorators are a relatively new feature in JavaScript that allows adding new behavior to existing functions and objects without modifying their underlying code. You can achieve it by using a special syntax that uses an @ symbol before the function name or object key.


2 Answers

The compiler expects your decorator to either be void or return a value that is compatible with A. It sees that you return a (msg:any) => any but can not draw the conclusion that this function is compatible with A.

If you want to get rid of the error, you can cast the ff to any when you return it, or maybe even to typeof A to communicate the intention clearer:

function xxx(arg: string) {     function f(target)     {         function ff(msg: string)         {             return new target(arg + ":" + msg)         }         return <typeof A><any>ff     }     return f } 

That said, it's probably not a good idea to replace classes like this, you should at least maintain the constructor:

TypeScript documentation:

NOTE Should you chose to return a new constructor function, you must take care to maintain the original prototype. The logic that applies decorators at runtime will not do this for you.

like image 166
Alex Avatar answered Sep 18 '22 06:09

Alex


This appears to be resolved by adding ES2016 or ES5 as the target in tsconfig.json

https://github.com/alsatian-test/alsatian/issues/344#issuecomment-290418311

like image 44
URL87 Avatar answered Sep 19 '22 06:09

URL87