You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在保留类型的前提下将对象所有值提升为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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.04 18:42:34