如何在保留类型的前提下将对象所有值提升为Option类型?
在fp-ts中实现对象值的Option提升(跳过已为Option的字段)
fp-ts没有直接提供满足你需求的现成函数,但可以通过组合现有工具函数自定义实现,同时完整保留原对象的类型结构。
实现思路
遍历对象的每个字段,通过类型守卫判断字段值是否已为Option类型:
- 非
Option类型的值,用fromNullable(或some,按需选择是否处理null/undefined)包装为Option - 已为
Option类型的值,直接保留原值
代码实现
首先定义类型守卫判断值是否为Option,再实现转换函数:
import { Option, isOption, fromNullable } from 'fp-ts/Option' import { pipe } from 'fp-ts/function' // 类型守卫:判断值是否属于Option类型 const isOptionType = <T>(val: unknown): val is Option<T> => isOption(val) // 自定义转换函数 const liftObjectToOption = <O extends Record<string, unknown>>(obj: O) => { const entries = Object.entries(obj).map(([key, val]) => { return [ key, isOptionType(val) ? val : fromNullable(val) ] as const }) return Object.fromEntries(entries) as { [K in keyof O]: O[K] extends Option<infer T> ? Option<T> : Option<O[K]> } }
使用示例
// 测试对象 const testObj = { a: 'hello', b: Option.some(123), c: null, d: undefined } const result = liftObjectToOption(testObj) // result类型:{ a: Option<string>, b: Option<number>, c: Option<null>, d: Option<undefined> }
贴合fp-ts风格的另一种实现
如果偏好函数式组合写法,可结合struct工具:
import { Option, fromNullable } from 'fp-ts/Option' import { struct } from 'fp-ts/Apply' import { pipe } from 'fp-ts/function' const liftObjectToOption = <O extends Record<string, unknown>>(obj: O) => { const lifted = {} as { [K in keyof O]: O[K] extends Option<infer T> ? Option<T> : Option<O[K]> } for (const key in obj) { const val = obj[key] lifted[key] = isOptionType(val) ? val : fromNullable(val) } return struct(Option).of(lifted) }
该实现同样严格保留类型结构,自动跳过已为Option的字段。
内容的提问来源于stack exchange,提问作者Danielo515
相关产品推荐
相关产品推荐

