FEATURED · 精选文章

Effect Schema 新增 `OptionFromUndefinedOr` 与 `OptionFromNullishOr`:将可选字段安全解码为 `Option`

发布时间 / 2026/9/14 14:16:36
来源 / 创域科博编辑部
栏目 / 资讯中心
Effect Schema 新增 `OptionFromUndefinedOr` 与 `OptionFromNullishOr`:将可选字段安全解码为 `Option` Effect Schema 新增OptionFromUndefinedOr与OptionFromNullishOr将可选字段安全解码为Option【免费下载链接】effectBuild production-ready applications in TypeScript项目地址: https://gitcode.com/GitHub_Trending/ef/effect本文基于effect仓库中.changeset/pre/add-schema-option-from-undefined-nullish.md变更记录系统讲解 Effect Schema 新增的OptionFromUndefinedOr与OptionFromNullishOr两个解码器/编码器schema的用途、语义、底层实现与实战用法帮助你在解析 API 响应、配置文件或数据库记录时把undefined/null这类缺省值统一建模为类型安全的OptionT。变更背景为什么要把undefined/null映射为Option在 TypeScript 中undefined与null常用于表示字段缺失或值不存在。但在真实业务里它们往往语义模糊一条 JSON 里某个键是缺失undefined、显式置空null还是真的没有值调用方很难区分而直接以T | undefined或T | null | undefined贯穿整个应用又会让每个使用点都要重复做判空。Effect 的OptionT类型恰好用来显式表达可能存在、也可能不存在Option.some(value)表示值存在Option.none()表示值不存在。变更记录.changeset/pre/add-schema-option-from-undefined-nullish.md宣告在 Schema 模块中新增两个便捷 schemaSchema: add OptionFromUndefinedOr and OptionFromNullishOr schemas.它们与既有的OptionFromNullOr构成完整三元组分别处理undefined、null、以及两者皆可nullish三种缺省语义让可选字段 →Option的转换从手工拼接变换变成一行声明。新增 API 概览三个从可选值构造 Option的 schema 全部定义在 packages/effect/src/Schema.ts自 3.10.0 起提供签名与语义如下Schema输入Encoded解码结果Type说明OptionFromNullOrST \| nullOptionTnull→None其余 →SomeOptionFromUndefinedOrST \| undefinedOptionTundefined→None其余 →SomeOptionFromNullishOrST \| null \| undefinedOptionTnull/undefined→None其余 →SomeOptionFromUndefinedOr对应 Schema.ts 中的 OptionFromUndefinedOr 定义类型签名继承自decodeToOptiontoTypeS, UndefinedOrS并带有Rebuild元数据以支持组合重建。OptionFromNullishOr对应 Schema.ts 中的 OptionFromNullishOr 定义额外接受一个可选配置options.onNoneEncoding: null | undefined用于指定None在编码回外部表示时的取值。三者都接收一个普通 schemaS作为值类型例如Schema.String、Schema.Number、Schema.FiniteFromString等返回的是可双向转换的 schema——既能把外部宽松表示解码为Option也能把Option编码回外部表示。解码与编码语义OptionFromUndefinedOrundefined与缺失等价undefined在 JavaScript/TypeScript 中天然表示未定义与 JSON 中键缺失高度契合。该 schema 的语义见 Schema.ts 中 OptionFromUndefinedOr 的 JSDoc解码undefined→Option.none()其他任何值 →Option.some(value)随后按内部 schema 校验如1→1。编码Option.none()→undefinedOption.some(value)→value。OptionFromNullishOrnull与undefined一视同仁很多外部系统如某些数据库、旧式 API同时用null和undefined表示无值。OptionFromNullishOr将二者统一折叠为None见 Schema.ts 中 OptionFromNullishOr 的 JSDoc解码null或undefined→Option.none()其余值 →Option.some(value)。编码Option.none()→ 由options.onNoneEncoding决定编码为null还是undefined默认值为undefinedOption.some(value)→value。提示若只想处理null而不想理会undefined请使用既有的OptionFromNullOr三个 schema 的边界划分正是为了让缺省语义与业务一一对应。底层实现decodeTo 变换原语新增 schema 并非从零实现而是建立在 Schema 既有变换机制之上。以 Schema.ts 中三个函数的实现 为例export function OptionFromNullOrS extends Constraint(schema: S): OptionFromNullOrS { return NullOr(schema).pipe(decodeTo( Option(toType(schema)), SchemaTransformation.optionFromNullOr() )) } export function OptionFromUndefinedOrS extends Constraint(schema: S): OptionFromUndefinedOrS { return UndefinedOr(schema).pipe(decodeTo( Option(toType(schema)), SchemaTransformation.optionFromUndefinedOr() )) } export function OptionFromNullishOrS extends Constraint( schema: S, options?: { onNoneEncoding: null | undefined } ): OptionFromNullishOrS { return NullishOr(schema).pipe(decodeTo( Option(toType(schema)), SchemaTransformation.optionFromNullishOr(options) )) }其构成分三层宽松输入 schemaNullOr/UndefinedOr/NullishOr在 Schema.ts 中定义为对原 schema 与Null、Undefined的 Union先把外部表示放行为T | null、T | undefined或T | null | undefined。decodeTo变换将上述宽松表示转换为内部目标类型OptiontoTypeS。变换原语真正执行Option与原始值互转的是 packages/effect/src/SchemaTransformation.ts 中的三个纯函数变换since 4.0.0optionFromNullOrT()SchemaTransformation.ts 定义decode: Option.fromNullOr、encode: Option.getOrNulloptionFromUndefinedOrT()SchemaTransformation.ts 定义decode: Option.fromUndefinedOr、encode: Option.getOrUndefinedoptionFromNullishOrT(options?)SchemaTransformation.ts 定义decode: Option.fromNullishOrencode则根据options?.onNoneEncoding null选择Option.getOrNull还是Option.getOrUndefined默认后者。从源码结构可以推断OptionFromNullishOr的onNoneEncoding参数在底层就是编码分支的选择开关传null时None编码为null否则编码为undefined。这些变换纯且同步pure and synchronous不引入异步或副作用。这种分层设计带来的直接好处你可以不依赖高层 schema直接用手写的Schema.NullOr(Schema.String)Schema.decodeTo(Schema.Option(Schema.String), SchemaTransformation.optionFromNullOr())组合出等价效果在自定义、内联场景下更灵活。实战用法解析 API 响应中的可选字段import { Option, Schema } from effect // 模拟外部返回某些字段缺失、某些显式为 null const User Schema.Struct({ id: Schema.Number, // 外部可能缺 key也可能给 undefined nickname: Schema.OptionFromUndefinedOr(Schema.String), // 外部可能给 null 或 undefined deletedAt: Schema.OptionFromNullishOr(Schema.DateTimeUtcFromSelf) }) const decode Schema.decodeUnknownSync(User) decode({ id: 1 }) // nickname: Option.none() decode({ id: 1, nickname: alice }) // nickname: Option.some(alice) decode({ id: 1, deletedAt: null }) // deletedAt: Option.none()解码后nickname/deletedAt都是类型安全的Option下游用Option.map、Option.getOrElse等操作即可安全取值不必再手工判断undefined/null。控制None的编码回写当需要把内部Option重新编码为外部表示时OptionFromNullishOr的onNoneEncoding决定了None落到哪个值import { Option, Schema } from effect const schema Schema.OptionFromNullishOr(Schema.String, { onNoneEncoding: null }) Schema.encodeSync(schema)(Option.some(v)) // v Schema.encodeSync(schema)(Option.none()) // null若不传onNoneEncoding则默认编码为undefinedconst schema2 Schema.OptionFromNullishOr(Schema.String) Schema.encodeSync(schema2)(Option.none()) // undefined提示仓库内package.json中effect: patch标记表明该变更属于补丁级非破坏性更新已有使用OptionFromNullOr的代码可以平滑升级无需迁移改动。测试验证与行为保证新 API 的行为在 packages/effect/test/schema/Schema.test.ts 中有完整覆盖自 3001 行起OptionFromUndefinedOrSchema.test.ts#L3001-L3017解码undefined→Option.none()1→Option.some(1)a→ 解码失败Expected a finite number说明内部 schema 校验仍然生效编码Option.none()→undefinedOption.some(1)→1。OptionFromNullishOr的两种配置Schema.test.ts#L3019-L3057{ onNoneEncoding: null }null/undefined均解码为NoneNone编码回null{ onNoneEncoding: undefined }解码行为相同None编码回undefined。测试同时验证了 Arbitrary 生成asserts.arbitrary().verifyGeneration()说明这两个 schema 也可以用于基于属性测试与数据生成场景。若你在自己的代码中使用可以参照该文件里的断言方式验证解码/编码往返round-trip一致性。总结OptionFromUndefinedOr(schema)处理T | undefinedundefined→NoneOptionFromNullishOr(schema, { onNoneEncoding })处理T | null | undefinednull与undefined统一为None编码回写可选null或undefined二者与OptionFromNullOr互补底层复用 SchemaTransformation.ts 的纯函数变换实现简洁、可组合新 API 自3.10.0起可用见 Schema.ts 中since 3.10.0标注属于补丁级变更可直接升级引入。需要声明3.10.0的版本号来自源码中since标注由于当前仓库包含预发布 changeset实际发布版本以官方发布渠道为准。【免费下载链接】effectBuild production-ready applications in TypeScript项目地址: https://gitcode.com/GitHub_Trending/ef/effect创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
RELATED — 相关阅读

相关资讯

LATEST — 最新资讯

最新发布

TODAY — 本日精选

新闻

WEEKLY — 本周精选

新闻

MONTHLY — 本月精选

新闻