typescript 如何只使第二个泛型参数为可选?

ulydmbyx  于 2023-03-13  发布在  TypeScript
关注(0)|答案(1)|浏览(212)

我有一组不相关的对象,但是我需要编写一个泛型函数来获取它们的值。
例如,给定:

type Circle = {
  color: string,
  radius: number,
}

type Person = {
  name: string,
  age: number,
}

我需要一个泛型函数,如下所示:

getData<Circle>('circle-id', ['radius']) // returns type { radius: number }

但我得到的最接近的解决方案需要两个泛型参数:

getData<Circle, ['radius']>('circle-id', ['radius'])

使得其使用不好。
目前,我的解决方案如下:

const getData = <Node, T extends Array<keyof Node>>(
  nodeId: string,
  attributes: T
): { [K in T[number]]: Node[K] } => {
 // ...
}

如何改进它,避免需要设置第二个泛型参数?
我知道使用咖喱很可能可以解决这个问题,但在我的特定情况下,我需要使getData返回一个可序列化的对象。
打字机游戏场

hfsqlsce

hfsqlsce1#

Alex韦恩说得对,你不能把推断类型和显式类型混在一起,但你 * 可以 * 通过在查找表的帮助下从参数中推断出其他类型来做到这一点:

type Circle = {
  color: string,
  radius: number,
}

type Person = {
  name: string,
  age: number,
}

// This is what makes it work
type Lookup = {
  'Circle': Circle,
  'Person': Person,
}

declare function getData<
  TKey extends keyof Lookup, 
  TData extends Lookup[TKey], 
  TEntries extends keyof TData
>(
  // Set the type by setting the key of the type lookup table
  key: TKey, 
  nodeId: string, 
  entires: TEntries[]
): { [K in typeof entires[number]]: TData[K] };

// String instead of generic
getData('Circle', 'circle-id', ['color']);

Playground

相关问题