定义类型时如何在打字稿中更改键名?

时间:2019-06-19 01:13:42

标签: typescript

如何在打字稿中更改键名?

我要进行如下更改。

type a = { num: number };
type b = Rename<a, 'number'>;
// b = { number: number; };

type aa = Array<{ num: number }>;
type bb = Rename<aa,'number'>;
// type bb = Array<{ number: number }>;

1 个答案:

答案 0 :(得分:1)

为此,您可能需要将conditional typesmapped types结合使用。这是一种可行的方法:

type RenameObject<T, K extends keyof any> = T extends object
  ? { [P in K]: T[keyof T] }
  : T;

type Rename<T extends object, K extends keyof any> = T extends Array<any>
  ? { [I in keyof T]: RenameObject<T[I], K> }
  : RenameObject<T, K>;

在这里,RenameObject<T, K>将保持不变的非对象类型,并使用键K将对象类型重命名为单属性对象,并且属性类型等于该类型的(联合) T的财产。如果Rename<T, K>是数组,则RenameObjectT应用于T元素;否则,它将仅对其应用RenameObject

这符合您的两个示例的要求:

type a = { num: number };
type b = Rename<a, "number">;
// type b = { number: number; };

type aa = Array<{ num: number }>;
type bb = Rename<aa, "number">;
// type bb = Array<{ number: number }>;

但是您没有说您想看到的事情通常会发生 ,因此上述定义具有某些行为,您可能会希望看到,也可能不想看到我们是否偏离了这些用例。

例如,我选择这样做是因为如果Ttuple类型,它将生成一个新的元组,其中每个元素都分别重命名:

type Tuples = Rename<[{a: string}, {b: number}, {c: boolean}], "hmm">
// type Tuples = [{ hmm: string; }, { hmm: number; }, { hmm: boolean; }]

如果T具有多个键,则生成的单键对象具有一个属性,该属性是T的所有属性类型的并集:

type MoreThanOneKey = Rename<{ a: string; b: number; c: boolean }, "hmm">;
// type MoreThanOneKey = {  hmm: string | number | boolean; }
// they get merged into one key

并且可选属性成为必需项(这是一个副作用,但是修复它会更加复杂,也许您不在乎):

type OptionalProperties = Rename<{ a?: string }, "hmm">;
// type OptionalProperties = {  hmm: string | undefined; }

并且嵌套对象仅重命名一级:

type NestedObjects = Rename<{ a: { b: string } }, "hmm">;
// type NestedObjects = {  hmm: { b: string; }; }

函数(从技术上讲是JS中的对象)变成了无用的never值对象:

type Functions = Rename<() => 1, "hmm">;
// type Functions = { hmm: never; }

因此,请按照自己的意愿做。希望能有所帮助。祝你好运!

Link to code