TypeScript Generic 将特定类型的所有类型更改为另一种

TypeScript Generic to change all types of a particular type to another

我试图想出一个打字稿类型,它接受一个对象并将类型 number 的所有键设置为 string。以下不起作用:

export type ChangeTypeOfKeys<T extends object> = {
  [key in keyof T]: key extends number ? string : T[key]
}

const c: ChangeTypeOfKeys<{ a: number, b: boolean }> = {
    a: 'ok',
    b: false,
}

结果类型应该是 { a: string, b: boolean },但我得到了一个 TS 错误:

Type 'string' is not assignable to type 'number'.(2322)
input.tsx(5, 29): The expected type comes from property 'a' which is declared here on type 'ChangeTypeOfKeys<{ a: number; b: boolean; }>'

TS playground link

我认为这个问题与我在 key in keyof T 中使用 key 的方式有关,因为用另一个参数替换 key extends number 是可行的:

export type ChangeTypeOfKeys<T extends object, Replace> = {
  [key in keyof T]: Replace extends number ? string : T[key]
}

const c: ChangeTypeOfKeys<{ a: number, b: boolean }, number> = {
    a: 'ok',
    b: 'ok',
}

TS playground link

不确定 key 是否有我在这里遗漏的任何特殊属性。 TIA!

要获取 key 引用的 属性 的值,请执行以下操作:

export type ChangeTypeOfKeys<T extends object> = {
  [key in keyof T]: T[key] extends number ? string : T[key]
  //                ^^^^^^
}

Playground Link


在您给出的示例中,key 的类型将始终为 string。绝对清楚,在您的代码中:

  • key指的是一个属性,
  • 的名字
  • T[key] 指的是类型 T 上名为 key 的 属性。

另请注意,extends object 允许 [] 类型(以及其他),这可能不是您想要的。尝试从 {}Record<string, any> 扩展。