使用Lodash/fp与TypeScript时set函数的类型匹配问题求助
解决Lodash/fp set函数的TypeScript类型推断问题
问题分析
Lodash/fp的set函数默认类型推断不会自动识别新增的对象属性,导致返回对象的类型缺失新增字段;而手动指定返回类型时,又无法校验属性路径和值是否与目标类型匹配,失去了TypeScript的类型安全校验能力。
解决方案:通过泛型约束实现类型安全的set调用
可以通过显式指定泛型参数,让set函数的路径、值与目标类型强绑定,既保证返回类型正确,又能校验路径和值的合法性。
方法1:调用时显式指定泛型参数
直接在调用set时,依次指定目标类型、属性路径、属性值类型三个泛型参数:
import { set } from 'lodash/fp'; interface NewObjType { foo: number; bar: number; } const obj = { foo: 1 }; // 泛型参数依次为:目标类型、路径、值类型 const newObj = set<NewObjType, 'bar', number>('bar')(2)(obj);
这样做的好处是:
- 路径
'bar'必须是NewObjType的合法键,否则TypeScript会报错 - 值
2必须符合NewObjType['bar']的类型(这里是number),否则报错 - 返回的
newObj类型直接是NewObjType,满足类型校验需求
方法2:封装类型安全的set工具函数
如果需要多次使用,可以封装一个更易用的类型安全版本,避免每次都写泛型参数:
import { set } from 'lodash/fp'; /** * 类型安全的set函数:确保路径是目标类型的键,值匹配对应类型 * @param path 目标类型的属性键 * @param value 对应属性的类型值 * @returns 可接收原对象的函数,返回包含新增/修改属性的目标类型对象 */ const safeSet = <Target, Key extends keyof Target>( path: Key, value: Target[Key] ) => set(path)(value) as <Source extends Omit<Target, Key>>(obj: Source) => Target; // 使用示例 interface NewObjType { foo: number; bar: number; } const obj = { foo: 1 }; const newObj = safeSet<NewObjType, 'bar'>('bar', 2)(obj);
这个封装函数会自动约束:
- 传入的路径必须是
Target类型的键 - 值的类型必须匹配
Target[Key] - 原对象只需包含
Target中除Key外的属性(通过Omit约束) - 返回对象直接是
Target类型
额外建议
检查你的@types/lodash-fp版本,升级到最新版(至少4.14.162以上),新版本对set的类型推断做了优化,部分场景下无需手动指定泛型就能得到正确的返回类型。
内容的提问来源于stack exchange,提问作者Raffa12341
相关产品推荐
相关产品推荐

