打字稿部分类型推断

Typescript partial type inference

我被这个难住了,不知道如何在没有第二个函数的情况下做到这一点:

interface Fixed { a: number }
const fn = <A, B extends {} = {}>(b: B) => {
  return b
}

fn({ a: 1 }) // { a: number }
fn<Fixed>({ a: 1 }) // {}

const fn2 = <A>() => <B extends {} = {}>(b: B) => {
  return b
}

const result = fn2<Fixed>()({ a: 1 }) // { a: number }

如果我固定类型 A,为什么 Typescript 不推断 B 的类型? 如果我 return 一个函数依次尝试推断 B 的类型,一切都会再次起作用。

类型推断基于全有或全无原则。第一种情况:

fn({ a: 1 })

没有提供泛型类型参数,因此它将推断两者:

  • B会根据函数参数推断为{ a: number }
  • A 将被推断为 unknown 因为它没有在函数的任何地方使用。

第二种情况:

fn<Fixed>({ a: 1 })

您指定了一种通用类型,不幸的是,这意味着 类型推断将不会用于其余类型参数 – 因此:

  • A 指定为 Fixed;
  • B 没有给出,所以不是推断它而是默认为 {}.

尽管这很烦人,但这正是 TypeScript 的工作方式。你的第二个例子有两个函数调用是这个问题的通常解决方法。

GitHub 上的相关 issue

我相信柯里化是解决方案。只是一个一般的例子:

const x = <I>(v: I) => <O>((v: I) => O) => O

// fully typed
x<number>(10)<string>((n) => `${n * 2}`);

// partial inference NO.1
x(10)<string>((n) => `${n * 2}`);

// partial inference NO.2
x<number>(10)((n) => `${n * 2}`);

// full inference
x(10)((n) => `${n * 2}`);