如何让TypeScript的DeepRemoveProps类型保留字段可选性?
修复TypeScript DeepRemoveProps的可选属性丢失问题
原DeepRemoveProps类型能够深层移除对象嵌套层级中的指定属性,但存在缺陷——处理后会丢失原字段的可选性标记(?),所有可选属性都会被转为必填属性。
原类型代码:
type DeepRemoveProps<T, P extends string> = T extends object ? { [K in Exclude<keyof T, P>]: DeepRemoveProps<T[K], P> } : T;
问题示例
当输入包含可选属性的类型时:
type Input = { a: { b?: string, c: { xx: 'removed', d?: string } }, yy: { removed: true }, xx: 'im removed' };
使用原类型处理后,b和d的可选标记会丢失,全部变为必填属性(即必须声明该属性,值可为string | undefined)。
修改后的实现
要保留属性的可选性(即属性可以不声明),我们可以借助Omit<T, P>工具类型——它会自动保留原类型中未被移除属性的可选性标记,再对每个属性进行递归处理,同时增加数组兼容逻辑:
type DeepRemoveProps<T, P extends string> = T extends object ? T extends Array<infer U> ? DeepRemoveProps<U, P>[] : { [K in keyof Omit<T, P>]: DeepRemoveProps<Omit<T, P>[K], P> } : T;
效果验证
用修改后的类型处理上述Input,得到的Result会正确保留可选性:
type Result = { a: { b?: string; c: { d?: string; }; }; };
内容的提问来源于stack exchange,提问作者Gershom Maes
相关产品推荐
相关产品推荐

