我想强制执行
copy
函数来扩展 original
函数。但诀窍是 - fnGenerator
的参数顺序是相反的。
可以做吗?
function fnGenerator<Original extends Copy, Copy extends Function>(copy:Copy,original:Original){}
function original(props:{a?:number,z:number}):number { return 2}
function copy(props:{a:number}):number { return 1}
// right now `original` has compilationerror instead of `copy`
fnGenerator(copy,original)
真实用例:
function fallback<OriginalFn extends Function>(props: {fallback:OriginalFn}) {
return function (target: any,
propertyKey: string,
descriptor: Omit<PropertyDescriptor,'value'> & { value?: OriginalFn}
) {
return descriptor
};
}
class MyClass1 {
// I expect a compilation error but it works
@fallback({fallback: (props: {x:number,z:number})=>{ return 0} })
static method1(pros:{x:number, z?: number}):number {
return 1
}
}
嗯,这很难。 充分讨论。
我的第一个解决方案。但它不起作用(请参阅链接中的游乐场)
解决方案:
function fallback2<MethodArgs extends unknown[],MethodReturn,FallbackFn extends (...args: MethodArgs) => MethodReturn>(props: { fallbackFn: FallbackFn }) {
return function(target: any,
propertyKey: string,
descriptor: TypedPropertyDescriptor<(...args: MethodArgs) => MethodReturn>
) {
// implement fallback logic...
return descriptor
};
}
class MyClass1 {
// I expect a compilation error because FallbackFn does not extend Method1Fn
@fallback2({ fallbackFn: (props: { x: number,y:number }):number => { return 0 } }) // works! why??
static method1Class1(pros: {x: number }): number {
return 1
}
@fallback2({ fallbackFn: ():number => { return 0 } }) // works! why??
static method1Class2(x:number): number {
return 1
}
// I expect a compilation error because FallbackFn does not extend Method1Fn
@fallback2({ fallbackFn: (y:number,z:number):number => { return 0 } }) // works! why??
static method1Class3(x:number): number {
return 1
}
@fallback2({ fallbackFn: (y:number,z?:number):number => { return 0 } }) // works! why??
static method1Class4(x:number): number {
return 1
}
}