如何编写符合内联泛型要求的TypeScript函数及解决MethodDecorator报错
问题1:内联泛型函数赋值报错
报错原因
要先明确两种泛型定义位置的差异:
Function2<T, S>的泛型参数是绑定在类型本身的,你声明变量时指定Function2<number, string>,泛型就已经固定,后续的函数实现只要匹配固定的类型规则即可,所以不会报错。Function3的泛型<T, S>是绑定在函数签名上的,约定了这个函数本身要支持调用方传入任意的T、S类型,泛型的确定时机是函数被调用的时候,不是你定义函数实现的时候。你在实现时直接硬写<Number, String>等于把泛型写死,不符合Function3要求的通用约定,自然会报错。
正确实现
如果你的需求就是固定泛型为number和string,直接用Function2的写法即可。如果确实要实现符合Function3类型的通用函数,可以这么写:
type ParamType<T> = T; type Function3 = <T, S>(obs: ParamType<T>) => ParamType<S>; const ofunc3: Function3 = (a) => { // 这里实现任意T转任意S的逻辑,根据你的业务需求调整 return a as unknown as S; }; // 调用时才传入具体的泛型参数 const res = ofunc3<number, string>(123);
问题2:方法装饰器泛型冲突报错
报错原因
TS内置的MethodDecorator类型本身已经自带了泛型定义,它的原生定义是:
type MethodDecorator = <T>( target: Object, propertyKey: string | symbol, descriptor: TypedPropertyDescriptor<T> ) => TypedPropertyDescriptor<T> | void;
你在返回的装饰器函数里又额外声明了<FuncType>泛型,相当于在两个不同的泛型上下文里定义了同名的类型规则,TS会认为两个类型是完全无关的,所以就会报"两个同名类型不相关"的错误。
正确实现
有两种写法可选:
写法1:自定义装饰器类型,不使用内置MethodDecorator
function Method2(): <FuncType>( target: Object, propertyKey: string | symbol, propertyDescriptor: TypedPropertyDescriptor<FuncType> ) => void { return (target, propertyKey, propertyDescriptor) => { // 赋值时加类型断言匹配泛型即可 propertyDescriptor.value = func1 as FuncType; }; }
写法2:直接使用内置MethodDecorator,不额外声明泛型
function Method2(): MethodDecorator { return (target, propertyKey, propertyDescriptor) => { // 直接用属性描述符自带的类型做断言 propertyDescriptor.value = func1 as typeof propertyDescriptor.value; }; }
内容的提问来源于stack exchange,提问作者Gayrat Vlasov
相关产品推荐
相关产品推荐

