Trình trang trí TypeScript báo 'Không thể xác định chữ ký của trình trang trí lớp khi được gọi như một biểu thức'
@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()
Khi biên dịch, nó báo:
decorator.ts(1,1): lỗi TS1238: Không thể xác nhận chữ ký của decorator lớp khi được gọi như một biểu thức. Kiểu '(msg: string) => any' không thể gán cho kiểu 'void'.
Nhưng mã JS được tạo ra thực thi tốt. Tôi không biết tại sao nó báo lỗi.
Câu trả lời #1
Vấn đề của tôi là tôi vẫn để "experimentalDecorators": true trong compilerOptions của tsconfig.json, nhưng điều đó không còn cần thiết trong phiên bản TypeScript mới nhất nữa.
Câu trả lời #2
Trên Vue+Vite, nó yêu cầu thêm:
"target": "ES5",
"emitDecoratorMetadata": true,
"experimentalDecorators": true
vào tsconfig.app.json, không phải tsconfig.json.
Câu trả lời #3
Trình biên dịch mong đợi decorator của bạn hoặc là void hoặc trả về một giá trị tương thích với A. Nó thấy rằng bạn trả về một (msg:any) => any nhưng không thể rút ra kết luận rằng hàm này tương thích với A.
Nếu bạn muốn loại bỏ lỗi, bạn có thể ép kiểu ff thành any khi trả về, hoặc thậm chí có thể thành typeof A để truyền đạt ý định rõ ràng hơn:
function xxx(arg: string)
{
function f(target)
{
function ff(msg: string)
{
return new target(arg + ":" + msg)
}
return <typeof A><any>ff
}
return f
}
Điều đó nói lên rằng, có lẽ không phải là một ý tưởng tốt để thay thế các lớp như thế này, bạn nên ít nhất giữ lại hàm tạo:
Tài liệu TypeScript:
LƯU Ý Nếu bạn chọn trả về một hàm tạo mới, bạn phải chú ý để duy trì prototype gốc. Logic áp dụng các decorator tại runtime sẽ không làm điều này cho bạn.
Câu trả lời #4
Điều này dường như được giải quyết bằng cách thêm ES2016 hoặc ES5 làm mục tiêu trong tsconfig.json
https://github.com/alsatian-test/alsatian/issues/344#issuecomment-290418311
Câu trả lời số 5
Tôi đã gặp vấn đề tương tự và nhận ra rằng tôi đang chọn thư mục src trong VS Code thay vì thư mục dự án. Khi tôi chọn thư mục dự án làm thư mục gốc, tệp tsconfig.json được nhận diện và lỗi đã biến mất.
Câu trả lời số 6
Tôi nhận được thông báo lỗi tương tự:
Không thể xác định chữ ký của trình trang trí lớp khi được gọi như một biểu thức. Thời gian chạy sẽ gọi trình trang trí với 2 đối số, nhưng trình trang trí yêu cầu 1 đối số.ts(1238)
Phiên bản Typescript của tôi là 5.0.4. Tôi đã giải quyết vấn đề này bằng cách thêm cái này vào tsconfig.json:
{
"compilerOptions": {
"experimentalDecorators": true, // the key line
},
}
