打字稿:使用通用类型键作为函数参数对象键

Typescript: Use generic type's keys as function's argument object keys

我有一个函数,其中泛型类型 T(即函数的 return 类型)是一个字典,键类型为 string,值类型为 unknown(因为它们可以是任何东西)。我希望这个函数接受的单个参数是一个对象,其键必须与通用类型 T 的键匹配。这本质上是一个函数,它在一些转换工作后将对象的 key/val 对映射到一组不同的值。

我想使用以下(注意函数参数中的索引类型)

export function convert<T extends Record<string, unknown>, S extends keyof any>(items: {
  [key: keyof typeof T]: string
}): T {
  //...do stuff
  return someObj as T;
}

这里重要的是keyof typeof T。这不起作用,因为我收到错误:

TS2693: 'T' only refers to a type, but is being used as a value here.

我不确定如何解决这个问题,或者为什么 T 在这里被视为一个值。有谁知道我做错了什么?我使用的各种实用程序类型和索引类型似乎无法解决我的问题。我希望函数的调用者在尝试传递不具有与实现中定义的类型匹配的所有键的对象时收到警告。

谢谢

你的语法有点错误,你想要的是映射类型而不是索引签名:

export function convert<T extends Record<string, unknown>>(items: {
  [key in keyof T]: string
}): T {
  //...do stuff
  return items as T;
}

Playground Link

您也可以使用 Record 类型而不是自定义映射类型:

export function convert<T extends Record<string, unknown>>(items: Record<keyof T, string>): T {
  //...do stuff
  return items as T;
}

Playground Link

如果您需要从 items 获取更多信息,您也可以反过来映射。另外我觉得这样更容易理解,但是显示的类型默认不展开:

export function convert<T extends Record<string, string>>(items: T): Record<keyof T, unknown> {
  //...do stuff
  return items;
}

Playground Link