【问题标题】:Typescript Functional Type Inference打字稿功能类型推断
【发布时间】:2019-04-10 11:00:56
【问题描述】:

我已经编写了这个简单的 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 这样的语言无需任何额外信息就能推断出类型。

【问题讨论】:

  • 编译器无法推断您的类型,因为它们没有出现在参数中。您希望它如何分辨?
  • 输入变量。

标签: javascript typescript types functional-programming type-inference


【解决方案1】:

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-06-09
    • 2020-04-02
    • 2020-12-20
    • 2016-08-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-08-12
    相关资源
    最近更新 更多