我正在尝试使foo
通用装饰器符合MethodDecorator
类型:
const foo: MethodDecorator = function <T extends Function = Function>(
target: object,
propertyKey: string | symbol,
descriptor: TypedPropertyDescriptor<T>
): TypedPropertyDescriptor<T> {
return {
configurable: true,
enumerable: false,
value: descriptor.value!.bind(null)
};
}
foo
可以直接用作辅助函数,我更愿意选择另外输入它作为通用函数。
Here is错误:
Type '<T extends Function = Function>(target: object, propertyKey: string | symbol, descriptor: TypedPr...' is not assignable to type 'MethodDecorator'.
Types of parameters 'descriptor' and 'descriptor' are incompatible.
Type 'TypedPropertyDescriptor<T>' is not assignable to type 'TypedPropertyDescriptor<Function>'.
Types of property 'value' are incompatible.
Type 'T | undefined' is not assignable to type 'Function | undefined'.
Type 'T' is not assignable to type 'Function | undefined'.
Type 'T' is not assignable to type 'Function'.
foo
如何符合MethodDecorator
?
答案 0 :(得分:1)
似乎MethodDecorator
不是generic type alias,因此无法缩小T
类型。
type Foo<T> = (x: T) => T; // this one is generic
type Bar = (x: T) => T; // and this is not
这是有道理的,因为foo
(即descriptor.value
具有bind
属性)中的假设通常不适用于MethodDecorator
。
由于type
仅仅是别名,我们可以定义自己的。
type TypedMethodDecorator = <T extends Function>(
target: Object,
propertyKey: string | symbol,
descriptor: TypedPropertyDescriptor<T>
) => TypedPropertyDescriptor<T> | void;
const foo: TypedMethodDecorator = function (target, propertyKey, descriptor) {
return {
configurable: true,
enumerable: false,
value: descriptor.value!.bind(null)
};
}
class C {
@foo
m() {
console.log('this:', this);
}
}
new C().m(); // 'this: null'
由于类型推断,编译器知道foo
是有效的装饰器。