代码之家  ›  专栏  ›  技术社区  ›  Finesse

如何生成一个通用函数值?

  •  2
  • Finesse  · 技术社区  · 7 年前

    请考虑以下代码:

    interface Foo<T1> {
      foo: string;
      baz: T1;
    }
    
    function toFoo<T2>(value: T2): Foo<T2> {
      return {
        foo: 'bar',
        baz: value
      };
    }
    
    // Actually this function is imported from an NPM package so I can't change it
    // The example is given for a better illustration
    function memoize<T3, T4>(func: (arg: T3) => T4): (arg: T3) => T4 {
      // Some implementation...
      return func;
    }
    
    const memoizedToFoo: {<T5>(value: T5): Foo<T5>} = // ???
    

    这个 toFoo 函数是泛型。我需要制作一个 豆腐 这也是通用的。我不能改变 memoize 类型和实现。如何实施 memoizedToFoo 所以它匹配给定的接口?

    我试过这个,但不起作用:

    const memoizedToFoo<T5> = memoize(toFoo<T5>); // unexpected <T5>
    
    2 回复  |  直到 7 年前
        1
  •  3
  •   unional    7 年前

    你能换一下吗 memorize() 功能?工作太辛苦了。

    以下内容将自动推断正确的类型:

    interface Foo<T1> {
      foo: string;
      baz: T1;
    }
    
    function toFoo<T2>(value: T2): Foo<T2> {
      return {
        foo: 'bar',
        baz: value
      };
    }
    
    function memoize<F extends Function>(func: F): F {
      // Some implementation...
      return func;
    }
    
    const memoizedToFoo = memoize(toFoo)
    

    Playground link

    更新:因为你不能改变 记忆() ,可以很好地覆盖它,如下所示:

    // memorize.ts
    import { memoize as origMemoize } from 'memoize'
    // or if it is commonJS
    import origMemoize from 'memoize'
    
    export const memoize = origMemoize as <F extends Function>(func: F) => F
    

    然后您可以将其作为原始文件使用:

    import { memoize } from './memoize'
    
    // code away
    

    请注意,此解决方案权衡了某种类型的安全性,因为 F 不限于 (arg: X) => Y

    要正确解决这一问题,我们需要: https://github.com/Microsoft/TypeScript/pull/22368

        2
  •  0
  •   Finesse    7 年前

    使记忆功能 any 泛型参数(如果需要)并将其强制转换为泛型函数类型:

    const memoizedToFoo: <T5>(value: T5) => Foo<T5> = memoize(toFoo);
    // or
    const memoizedToFoo: typeof toFoo = memoize(toFoo);
    
    推荐文章