gpt4 book ai didi

typescript - 如何在 TypeScript 中获取对象中所有键值对的联合类型?

转载 作者:行者123 更新时间:2023-12-04 12:54:05 25 4
gpt4 key购买 nike

假设我有一个这样的对象:

const person = {
id: 87
name: 'Some Name',
address: {
street: 'Some street',
country: 'Some country'
}
}
我想得到一个类型,它是所有键值对的并集。所以类型应该是:
{ id: number } | { name: string } | { address: { street: string; country: string; } }
那怎么办呢?我试过这个:
type PersonInfo = {
id: number;
name: string;
address: {
street: string;
country: string;
}
}

type PersonMap<M extends { [index: string]: any }> = {
[Key in keyof M]: M[Key]
};

type PersonTest1 = PersonMap<PersonInfo>[keyof PersonMap<PersonInfo>];
// Returns "number | string | { street: string; country: string; }"

type PersonTest2 = PersonMap<PersonInfo>;
// Returns { id: number; name: string; address: { street: string; country: string;} }
如何获得上述联合类型?

最佳答案

看起来你想要一个形式为 UnionOfSingleKeyObjects<T> 的类型函数这将转换为对象类型 T成单键对象类型的联合,其中每个键在 keyof T恰好出现一次。根据您的用例,您可以定义这样的类型函数:

type UnionOfSingleKeyObjects<T extends object> = 
{ [K in keyof T]-?: { [P in K]: T[P] } }[keyof T]
并验证它是否适用于 PersonInfo如预期的:
type PersonKVPairs = UnionOfSingleKeyObjects<PersonInfo>
/* type PersonKVPairs = {
id: number;
} | {
name: string;
} | {
address: {
street: string;
country: string;
};
} */
UnionOfSingleKeyObjects的定义是 mapped type我们迭代每个键类型 Kkeyof T ,为每个键计算有问题的单键对象,然后 index into itkeyof T获得所有单键对象类型的联合。
您可以使用 distributive conditional types 而不是索引到映射类型获得相同的效果:
type UnionOfSingleKeyObjects<T extends object> =
keyof T extends infer K ? K extends keyof T ?
{ [P in K]: T[P] } : never : never
无论哪种方式都有效;我倾向于使用映射类型,因为它们比条件类型分布更容易解释。

在这两种方法中,键为 K 的单键对象写成 {[P in K]: T[P] } .这也可以写成 Record<K, T[K]>使用 the Record<K, V> utility type ,或作为 Pick<T, K>使用 the Pick<T, K> utility type .这些其他版本各有优缺点,可能会改变类型在 IntelliSense quickinfo 中的显示方式以及是否可选/ readonly键保持可选/ readonly在输出中。如果您关心保留这些修饰符并且不想看到 PickRecord在你的 quickinfo 中,你可以这样写 {[P in keyof Pick<T, K>]: T[P]} , 像这样:
type UnionOfSingleKeyObjects<T extends object> =
{ [K in keyof T]-?: { [P in keyof Pick<T, K>]: T[P] } }[keyof T]
我们可以看到保留了这样的修饰符:
type Example = UnionOfSingleKeyObjects<{ a?: string, readonly b: number }>
/* type Example = {
a?: string;
} | {
readonly b: number;
} */
同样,根据您的用例,您可能会或可能不会关心这些事情。
Playground link to code

关于typescript - 如何在 TypeScript 中获取对象中所有键值对的联合类型?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/69105062/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com