TypeScript对象条件键名与类型重映射:混合场景失效问题
解决方案
要实现每个字段既可保留原键形式,也可重映射为${键名}.$func形式,同时支持混合使用两种形式,需要调整类型逻辑,让每个字段独立选择两种形式之一,并且所有字段都必须被覆盖。
修正后的类型代码
export const FUNC_ENDING_HINT = "$func" as const; // 定义单个字段的两种可选形式:原键或重映射后的键 type FieldOption<TD, K extends keyof TD> = | { [P in K]: TD[K] } | { [P in `${K}.${typeof FUNC_ENDING_HINT}`]: Record<string, any[]> }; // 递归组合所有字段的可选形式,生成支持混合场景的类型 export type DataOrFuncFromObject<TD> = keyof TD extends infer Ks ? Ks extends keyof TD ? FieldOption<TD, Ks> extends infer FC ? FC & DataOrFuncFromObject<Omit<TD, Ks>> : never : {} : never; // 测试用Schema type Schema = { col1: string; col2: string; }; // 验证场景 const basic: DataOrFuncFromObject<Schema> = { col1: "", col2: "" }; //@ts-expect-error 缺少col2的对应字段(原键或$func键) const incompleteBasic: DataOrFuncFromObject<Schema> = { col1: "", }; //@ts-expect-error 缺少col1的对应字段(原键或$func键) const incompleteFunc: DataOrFuncFromObject<Schema> = { "col2.$func": { func: [] }, }; const funcs: DataOrFuncFromObject<Schema> = { "col1.$func": { func: [] }, "col2.$func": { func: [] }, }; // 混合场景现在可以正常通过类型检查 const mixed: DataOrFuncFromObject<Schema> = { col1: "", "col2.$func": { func: [] }, };
类型逻辑说明
FieldOption类型:为单个字段定义两种可选结构——要么是原键+对应类型值,要么是重映射后的${键名}.$func键+函数参数结构。DataOrFuncFromObject类型:通过递归方式,将每个字段的可选形式交叉组合,生成所有可能的字段组合类型,包括全原键、全重映射键、以及混合形式。- 完整性校验:递归组合的方式确保所有字段都必须存在对应的原键或重映射键,避免出现缺失字段的情况。
内容的提问来源于stack exchange,提问作者user5480949
相关产品推荐
相关产品推荐

