我的测试代码如下:
function test(target: Object, propertyKey: string, descriptor: TypedPropertyDescriptor<any>) {
return descriptor;
}
class Test {
@test
hello() {
}
}
但是编译器给我错误
Error:(33, 5) TS1241: Unable to resolve signature of method decorator when called as an expression.
Supplied parameters do not match any signature of call target.
我已经指定了:
--experimentalDecorators --emitDecoratorMetadata
使用
--target ES5 --emitDecoratorMetadata --experimentalDecorators
或使用以下配置:
{
"compilerOptions": {
"emitDecoratorMetadata": true,
"experimentalDecorators": true,
"target": "ES5"
}
}
TypeScript 似乎期望装饰器函数的返回类型为“any”或“void”。因此,在下面的示例中,如果我们将
: any
添加到末尾,它就会正常工作。
function test(target: Object,
propertyKey: string,
descriptor: TypedPropertyDescriptor<any>): any {
return descriptor;
}
随着时间的推移,这个神秘的错误消息似乎有多个根本原因。截至 2019 年底,我可以收集到以下信息:
@f()
处发出 TS1241 信号,但不在 @g()
处发出信号:function f() {
console.log("f(): evaluated");
return function (targetClass: any, propertyKey: string, descriptor: TypedPropertyDescriptor<() => void>) {
console.log("f(): called with " + arguments.length + " arguments");
}
}
function g() {
console.log("g(): evaluated");
return function (target: any, propertyKey: string) {
console.log("g(): called with " + arguments.length + " arguments");
}
}
class C {
@f() // TypeScript signals TS1241 here
@g() // but not there
method() { }
}
{"compilerOptions": { "target": "ES3" } }
运行上述代码会产生f():计算出 main-2.js 第 1134 行 >评估:9:13 g():评估 main-2.js 第 1134 行 > eval:15:13 g():使用 2 个参数调用 main-2.js 第 1134 行 > eval:17:17 f():使用 2 个参数调用(💡 当 在
typescriptlang.org/play
上尝试代码时,首先在浏览器的开发人员工具中打开 JavaScript 控制台;然后单击“运行”)。"target": "ES5"
下的代码导致 f(): 评估 main-2.js 第 1134 行 > eval:9:13 g():评估 main-2.js 第 1134 行 > eval:15:13 g():使用 3 个参数调用 main-2.js 第 1134 行 > eval:17:17 f():使用 3 个参数调用因此,在这种情况下,TypeScript 对
@f()
(以及 @g()
)非常满意。因此,最简单的解决方法是假装第三个参数是可选的,即
function f() {
console.log("f(): evaluated");
return function (targetClass: any, propertyKey: string, descriptor?: TypedPropertyDescriptor<() => void>) {
console.log("f(): called with " + arguments.length + " arguments");
}
}
class C {
@f()
method() { }
}
"target": "ES3"
和 "target": "ES5"
下都能成功进行类型检查。
如果使用angular-meteor,这个“作弊”尤其重要,在这种情况下,你绝对不想想要弄乱
"target"
中的tsconfig.json
设置。
在 tsconfig 中添加此命令以使用装饰器。
{
"compilerOptions": {
"emitDecoratorMetadata": true,
"experimentalDecorators": true,
"target": "ES5"
}
}
装饰器函数应该是这样的。
function(target: any, key: string, descriptor: PropertyDescriptor) {
const originalMethod = descriptor.value;
descriptor.value = async function(...args: any) {
try {
const result = await originalMethod.apply(this, args);
return result;
} catch (error) {
console.log(error)
}
};
return descriptor;
};
如果您使用
,您也可能会收到此错误() => {}
函数表示法,切换到常规表示法
函数(){}
修复此错误。您必须将
tsconfig.json
添加到您的项目目录中。然后,如果您愿意,可以按照此config
代码进行操作。
{
"compilerOptions": {
"lib": [
"es5",
"es6"
],
"target": "es6",
"module": "commonjs",
"moduleResolution": "node",
"outDir": "./build",
"emitDecoratorMetadata": true,
"experimentalDecorators": true,
"sourceMap": true,
"esModuleInterop": true
}
}
我在 vsCode 中报告了此错误,但在编译时/运行时一切正常。
我通过检查
js/ts.implicitProjectConfig.experimentalDecorators
设置修复了它。
最近 tsyringe 也出现同样的问题。我在装饰器之前添加@ts-ignore...
//@ts-ignore
public constructor(@inject(MongoClient) private client: MongoClient) {
我使用
NestJS + Deno + GraphQL + npm packages
找到了针对此问题以及项目中相关错误的单行解决方案。其他解决方案对我不起作用。因此,在这里分享它,因为它可能会帮助别人节省一些时间。它可能与使用其他运行时(如 Bun、Node)的项目相关。
您可以在这里找到详细答案>> https://stackoverflow.com/a/79107940/13607767