修复TypeScript的AddPostfixes泛型:实现动态添加属性后缀
解决TypeScript泛型添加指定后缀属性并继承可选性的问题
正确实现
以下是修复后的AddPostfixes泛型,可实现为原类型添加指定后缀的属性,同时保留原属性的可选性:
// 辅助类型:判断属性是否为可选 type IsOptional<T, K extends keyof T> = K extends keyof Required<T> ? false : true; type AddPostfixes<T, Postfixes extends Record<string, unknown>> = // 保留原类型 T & // 生成原属性为必选的后缀属性(必选) { [KP in `${keyof T & string}${keyof Postfixes & string}` as IsOptional<T, KP extends `${infer K}${string}` ? K : never> extends false ? KP : never]: KP extends `${infer K}${infer P}` ? K extends keyof T ? P extends keyof Postfixes ? Postfixes[P] : never : never : never } & // 生成原属性为可选的后缀属性(可选) { [KP in `${keyof T & string}${keyof Postfixes & string}` as IsOptional<T, KP extends `${infer K}${string}` ? K : never> extends true ? KP : never]?: KP extends `${infer K}${infer P}` ? K extends keyof T ? P extends keyof Postfixes ? Postfixes[P] : never : never : never };
实现说明
- 生成后缀属性:通过模板字符串类型
${keyof T & string}${keyof Postfixes & string},遍历原类型所有属性与所有后缀的组合,生成新的属性名。 - 绑定对应类型:对每个组合的属性名,解析出原属性名
K和后缀P,返回Postfixes[P]作为该属性的类型,确保每个后缀对应正确的类型。 - 继承可选性:通过
IsOptional辅助类型判断原属性是否为可选,分别生成必选/可选的后缀属性,保证新属性的可选性与原属性一致。
验证效果
示例1:全可选原类型
type OriginalType = { name?: string; age?: number; }; type ModifiedType = AddPostfixes< OriginalType, { Postfix1: number; Postfix2: string; Postfix3: boolean } >; // 最终类型符合预期: // { // name?: string; // age?: number; // namePostfix1?: number; // namePostfix2?: string; // namePostfix3?: boolean; // agePostfix1?: number; // agePostfix2?: string; // agePostfix3?: boolean; // }
示例2:混合可选/必选原类型
type MyOriginalType = { name: string; age?: number; }; type PostfixedType = AddPostfixes<MyOriginalType, { Postfix1: number; Postfix2: string; Postfix3: boolean }>; // 最终类型: // { // name: string; // age?: number; // namePostfix1: number; // namePostfix2: string; // namePostfix3: boolean; // agePostfix1?: number; // agePostfix2?: string; // agePostfix3?: boolean; // }
原实现问题分析
- 逻辑颠倒:原实现试图从原属性名中解析后缀,而非从生成的新属性名中拆分原属性与后缀,导致类型匹配错误。
- 类型绑定错误:返回的是原属性类型或所有后缀类型的联合值,未对应到具体后缀的类型。
- 未处理可选性:未继承原属性的可选状态,导致后缀属性的可选性不符合预期。
内容的提问来源于stack exchange,提问作者Andy
相关产品推荐
相关产品推荐

