代码之家  ›  专栏  ›  技术社区  ›  Mateja Petrovic

Typescript函数类型推理

  •  0
  • Mateja Petrovic  · 技术社区  · 7 年前

    我已经写了这个简单的compose函数,它工作得很好。然而,为了确保类型安全,我不得不使用泛型为编译器提供类型提示,尽管很容易推断出“upperCaseAndLog”的签名。

    const compose = <T, R>(...fns: Array<(a: any) => any>) => (a: T): R =>
      fns.reduce((b, f) => f(b), a);
    
    const greet = (s: string) => "Hello " + s;
    const toUpperCase = (s: string) => s.toUpperCase();
    const log = console.log;
    
    const upperCaseAndLog = compose<string, void>(
      greet,
      toUpperCase,
      log
    );
    
    upperCaseAndLog("bill");

    我是否遗漏了什么,有没有更优雅的方法来实现同样的目标?我假设像F#或Haskell这样的语言能够在没有任何附加信息的情况下推断类型。

    1 回复  |  直到 7 年前
        1
  •  1
  •   Titian Cernicova-Dragomir    7 年前

    Typescript不能推断这样的链接类型(链接的意义是函数的参数依赖于上一个函数的结果)。

    compose

    type Fn<A, R> = (a: A) => R // just to be a bit shorter in the compose signature, you can use teh function signature directly  
    function compose<T, P1, P2, R>(fn1: Fn<T, P1>, fn2: Fn<P1, P2>, f3: Fn<P2, R>) : Fn<T, R>
    function compose<T, P1, R>(fn1: Fn<T, P1>, f2: Fn<P1, R>) : Fn<T, R>
    function compose(...fns: Array<(a: any) => any>) {
        return function (a: any) {
            return fns.reduce((b, f) => f(b), a);
        }
    }
    
    const greet = (s: string) => "Hello " + s;
    const toUpperCase = (s: string) => s.toUpperCase();
    const log = console.log;
    
    const upperCaseAndLog = compose(
        greet,
        toUpperCase,
        log
    );
    
    upperCaseAndLog("bill");//(a: string) => void