如何用类似TypeScript Omit的技术实现对象按类型的属性合并与过滤?
基于TypeScript类型实现对象属性覆盖与额外键过滤
需求很明确:用自定义配置(customConfig,类型CustomRequestInit)中属于RequestInit的属性覆盖默认配置(config,类型RequestInit)的同名属性,同时过滤掉自定义配置里不属于RequestInit的额外属性(比如示例中的params)。
1. 定义类型工具
首先需要一个类型,用来提取CustomRequestInit中所有属于RequestInit的属性,确保后续处理的对象类型合规:
type FilteredCustomConfig = Pick<CustomRequestInit, keyof RequestInit>;
这个类型会自动剔除CustomRequestInit里不在RequestInit中的键,只保留两者共有的属性类型。
2. 实现合并过滤函数
接下来写一个工具函数,完成属性覆盖和额外键过滤的逻辑:
function mergeConfigs( defaultConfig: RequestInit, customConfig: CustomRequestInit ): RequestInit { // 提取customConfig中属于RequestInit的属性 const filteredCustom = {} as FilteredCustomConfig; for (const key of Object.keys(customConfig) as Array<keyof CustomRequestInit>) { if (key in defaultConfig) { filteredCustom[key] = customConfig[key]; } } // 合并:custom属性覆盖default,仅保留RequestInit的键 return { ...defaultConfig, ...filteredCustom, // 若需处理headers这类嵌套对象的深合并,可单独处理 headers: { ...defaultConfig.headers, ...filteredCustom.headers } }; }
如果不需要深合并(比如示例中headers完全一致),直接用{...defaultConfig, ...filteredCustom}即可;如果有嵌套属性需要合并,单独处理对应字段即可。
3. 示例验证
用你给出的示例数据测试:
// 默认配置 const config: RequestInit = { headers: { 'Content-Type': 'application/json', }, }; // 自定义配置类型与实例 interface CustomRequestInit extends RequestInit { params: Record<string, string>; } const customConfig: CustomRequestInit = { mode: 'cors', headers: { 'Content-Type': 'application/json', }, params: { 'tk': '2edr3q2afa3', } }; // 合并后的结果 const mergedConfig = mergeConfigs(config, customConfig); console.log(mergedConfig); // 输出:{ headers: { 'Content-Type': 'application/json' }, mode: 'cors' } // 额外的params被过滤,mode因默认无此属性直接添加
4. 简化写法(利用类型断言)
如果能确保customConfig的属性类型与RequestInit兼容,也可以用更简洁的类型断言写法跳过编译时检查:
function mergeConfigsSimple( defaultConfig: RequestInit, customConfig: CustomRequestInit ): RequestInit { return { ...defaultConfig, ...(customConfig as unknown as RequestInit) }; }
内容的提问来源于stack exchange,提问作者Lobanov Ivan
相关产品推荐
相关产品推荐

