强制两个函数具有相同的签名(仅通过使用类型)

问题描述 投票:0回答:1

我想强制执行

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
  }
}
typescript typescript-generics
1个回答
0
投票

嗯,这很难。 充分讨论

我的第一个解决方案。但它不起作用(请参阅链接中的游乐场)

我以为存在打字稿错误。

那么它只是方法参数双方差

解决方案

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
  }
}
© www.soinside.com 2019 - 2024. All rights reserved.