如何在TypeScript中扁平化嵌套接口类型?附示例代码
TypeScript 对象类型扁平化实现
先看原始类型定义:
type MyType = { name: string; gender?: "male" | "female"; section: { a: string; b: string; }; }
我们需要将其转换为键名用.拼接的扁平化类型:
{ name: string; gender?: "male" | "female"; "section.a": string; "section.b": string; }
可以通过递归工具类型实现这个需求,下面是完整的实现代码:
// 递归扁平化对象类型的工具类型 type Flatten<T, Prefix extends string = ""> = T extends object ? { [K in keyof T as Prefix extends "" ? K : `${Prefix}.${string & K}`]: T[K] extends object ? Flatten<T[K], `${Prefix extends "" ? "" : `${Prefix}.`}${string & K}`> : T[K]; } extends infer O ? { [K in keyof O]: O[K] } : never : T; // 测试使用 type FlattenedMyType = Flatten<MyType>;
工作原理说明
- 类型判断:首先检查当前类型
T是否为对象类型,非对象类型直接返回原类型 - 键名拼接:遍历对象的每个键
K,根据传入的前缀Prefix拼接新键名——前缀为空时用原键名,否则用前缀.键名的格式 - 递归处理:如果当前键对应的类型还是对象,就递归调用
Flatten,将当前拼接好的键名作为新前缀传入,继续深层扁平化 - 类型整理:通过
infer和重新映射,确保最终生成的类型结构符合预期
这个工具类型还支持多层嵌套的对象,比如:
type NestedType = { id: number; info: { contact: { email: string; phone?: string; }; }; }; type FlattenedNested = Flatten<NestedType>; // 生成的类型: // { // id: number; // "info.contact.email": string; // "info.contact.phone"?: string | undefined; // }
内容的提问来源于stack exchange,提问作者kitta
相关产品推荐
相关产品推荐

