如何为多类型配置读取函数实现TypeScript强类型定义?
解决配置读取函数的强类型定义问题
核心思路
通过映射类型和条件类型建立输入配置与输出类型的精确对应关系,替代之前的联合类型方案,让TypeScript能准确推断每个返回值的类型。
完整实现代码
// 原始配置类型定义 type StringSetting = 'outputPath' | 'fileName' type StringSettingWithParam = 'emailAddress' | 'homeDirectory' type ArrayOfStringsSetting = 'inputPaths' // 建立配置名到返回类型的映射 type SettingReturnType = { [K in StringSetting]: string; } & { [K in StringSettingWithParam]: string; } & { [K in ArrayOfStringsSetting]: string[]; }; // 定义单个配置项的输入类型(自动判断是否需要param参数) type SettingInput<K extends keyof SettingReturnType> = K extends StringSettingWithParam ? { setting: K; param: string } : { setting: K }; // 最终的强类型函数 function getSettings<T extends Record<string, keyof SettingReturnType>>( settings: { [K in keyof T]: SettingInput<T[K]> } ): { [K in keyof T]: SettingReturnType[T[K]] } { // 实际配置读取逻辑示例 const result: Record<string, unknown> = {}; for (const key in settings) { const { setting, param } = settings[key]; switch (setting) { case 'outputPath': result[key] = '/home/user'; break; case 'emailAddress': result[key] = `${param}@bar.com`; break; case 'inputPaths': result[key] = ['/usr/var/output', '/home/user/output']; break; // 其他配置项的读取逻辑 default: result[key] = ''; } } return result as { [K in keyof T]: SettingReturnType[T[K]] }; } // 使用示例 const config = getSettings({ a: { setting: 'outputPath' }, b: { setting: 'emailAddress', param: 'userA' }, c: { setting: 'inputPaths' } }); // 类型推断完全正确: // config.a → string // config.b → string // config.c → string[]
关键步骤说明
SettingReturnType映射类型:把每种配置名和它对应的返回类型绑定,让TypeScript能通过配置名直接找到返回类型。SettingInput条件类型:自动判断配置是否需要param参数——如果是StringSettingWithParam类型的配置,强制要求传入param,否则不允许出现该字段。- 函数泛型约束:泛型
T限定为输入对象的键到配置名的映射,输入参数和返回值都通过T做逐键的类型映射,确保输入和输出的键完全对应,值类型精确匹配。
为什么之前的方案有问题
之前用Parameters<Processors>[0]会把所有输入类型合并成一个松散的联合类型,TypeScript无法区分每个配置项的具体类型,导致返回值只能推断为联合类型,无法做到精确的键值对应。
内容的提问来源于stack exchange,提问作者AnLoDreAs
相关产品推荐
相关产品推荐

