0

如何使Y函数中的必需类型参数与另一个类型参数一起工作,K后者仅用作记录R = {a: 'aaa', b: 'bbb'}查找中的键并且不应该显式提供?类型参数K应该从函数的第一个参数的值推断k出来foo。然后我想K用来查找一个类型,R以便我可以将它用于函数的其他参数。

为了只允许需要第一个类型参数YK参数需要有一个默认值。但是这个默认值打破了R[K]when 的推断,而不是根据kieR[typeof k]的值推断"aaa"if kwas "a",它使用默认的KieR[keyof R]解析为记录中所有类型的联合,R"aaa" | "bbb"忽略k

是否可以在没有显式传递的情况下从值解析y: R[keyof K]where的类型推断,但仍然允许所需的类型参数?KkKY

type R = {
  a: 'aaa',
  b: 'bbb',
}

type Foo = <
  Y,
  K extends keyof R = keyof R,
>(k: K, f: (x: R[K], y: Y) => any) => any

const foo: Foo = (x, y) => null

// With no type params Rec[K] is correctly inferred from K: 'a'
foo('a', (x, y) => null) // x: "aaa"; y: unknown

// When passing the Y type param, Rec[K] ignores the K: 'a'
foo<number>('a', (x, y) => null) // x: "aaa" | "bbb"; y: number

// When passing both Y and K it works
foo<number, 'a'>('a', (x, y) => null) // x: "aaa"; y: number

我只能通过对函数进行柯里化来使其工作,因此每个类型参数都属于一个单独的函数:

type FooCurried = <K extends keyof R = keyof R>(k: K) =>
  <Y>(f: (x: R[K], y: Y) => any) =>
    any

const fooCurried: FooCurried = x => y => null

fooCurried('a')<number>((x, y) => null) // x: "aaa"; y: number
4

1 回答 1

0

发现了一个非常相似的问题,其中接受的答案说这只能通过对函数进行柯里化来完成,就像我在示例中所做的那样。

于 2021-02-10T12:26:40.910 回答