javascript - Không thể sử dụng các decorator ecmascript mới trong typescript 2.4.2
Đây là ví dụ mã của tôi:
function enumerable(value: boolean) {
return function (target: any, propertyKey: string, descriptor: PropertyDescriptor) {
descriptor.enumerable = value;
};
}
class A {
@enumerable(false)
a: number = 1
b: number = 2
myMethod () {}
}
const a = new A()
Dù tôi có thử gì đi chăng nữa, tôi cũng nhận được:
D:(real path removed)/first-try-typescript>tsc --emitDecoratorMetadata --experimentalDecorators decorators.ts
decorators.ts(8,3): error TS1240: Unable to resolve signature of property decorator when called as an expression.
Tôi đã thử mọi thứ từ các gợi ý câu hỏi giống nhau trên Stack Overflow:
- thêm emitDecoratorMetadata & experimentalDecorators vào tsconfig
- chạy tsc --emitDecoratorMetadata --experimentalDecorators
- thêm
:anyđể đánh dấu hàm decorator trả về giá trị - thêm kiểu
descriptor: TypedPropertyDescriptor<any>
Tôi luôn nhận được lỗi này. Cả trong terminal và trong gợi ý mã của Webstorm. Trình trang trí phương thức - cũng giống như vậy (xem ví dụ bên dưới).
function test(target: Object,
propertyKey: string,
descriptor: TypedPropertyDescriptor<any>): any {
return descriptor;
}
class A {
a: number = 1
b: number = 2
@test
myMethod () {}
}
const a = new A()
Mã mới nhất có ở đây - https://github.com/rantiev/first-try-typescript
Câu trả lời #1
Đáng tiếc, trang trí thuộc tính không có quyền truy cập vào mô tả thuộc tính, vì các thuộc tính tồn tại trên thể hiện lớp, trong khi các trình trang trí được đánh giá trước khi bất kỳ thể hiện nào có thể tồn tại. Ngoài ra, bạn chỉ có thể sử dụng chữ ký sau cho một trình trang trí thuộc tính:
function (target: any, propKey: string | symbol)
Vậy ở đây không có mô tả nào.
Bạn cũng không thể chỉ làm Object.defineProperty(target, propKey.toString, { enumerable: false, value: ... }) vì điều đó sẽ được chia sẻ giữa tất cả các thể hiện của lớp của bạn, tức là việc đặt một thuộc tính trong một thể hiện sẽ bị rò rỉ sang thể hiện khác.
Việc đạt được những gì bạn đang làm là có thể, nhưng hơi phức tạp. Những gì tôi thường làm là tạo một getter trên prototype để tạo mô tả thuộc tính mong muốn ngay khi cần. Một thứ gì đó như:
function enumerable(value: boolean) {
return function (target: any, propKey: string | symbol) {
Object.defineProperty(target, propKey, {
get: function () {
// In here, 'this' will refer to the class instance.
Object.defineProperty(this, propKey.toString(), {
value: undefined,
enumerable: value
});
},
set: function (setValue: any) {
// In here, 'this' will refer to the class instance.
Object.defineProperty(this, propKey.toString(), {
value: setValue,
enumerable: value
});
}
});
};
}
Chức năng get/set 'bên ngoài' chỉ chạy một lần, vì thuộc tính của instance sẽ che khuất nó sau khi mô tả thuộc tính đã được tạo trên instance.
