如何以更符合TypeScript风格的方式向可选字段传递undefined?
TypeScript 开启精确可选属性类型后,优雅处理可选属性赋值问题
我目前用以下方式处理向可选属性传递可能为undefined的对象:
type Foo = { opt?: string } const opt = Math.floor(Math.random() * 2) == 0 ? "Hello" : undefined const bar: Foo = { } if(opt !== undefined){ bar.opt = opt }
这种用if判断后再赋值的方式略显繁琐,有没有更符合TypeScript风格的实现方式?我尝试了如下写法:
type Foo = { opt?: string } const opt = Math.floor(Math.random() * 2) == 0 ? "Hello" : undefined const bar: Foo = { opt }
但VSCode中出现了如下错误:
Type 'undefined' is not assignable to type 'string'.
更新说明:该行为是开启TypeScript的**精确可选属性类型(exactOptionalPropertyTypes)**选项后的预期表现,我已启用该选项。
解决方案
由于开启exactOptionalPropertyTypes后,可选属性opt?: string的规则是:属性要么不存在,要么存在且值为string,不允许显式赋值undefined。以下是几种更优雅的实现方式:
1. 对象展开+条件过滤(推荐)
通过条件判断动态生成包含属性的对象,再展开到目标对象中。当opt为undefined时,不会向对象中添加该属性,完全符合精确可选属性的要求:
type Foo = { opt?: string } const opt = Math.floor(Math.random() * 2) == 0 ? "Hello" : undefined const bar: Foo = { ...(opt !== undefined ? { opt } : {}) }
2. 类型断言(适合简单场景)
如果能确保类型安全,可以直接将opt断言为符合可选属性要求的类型,绕过类型检查:
const bar: Foo = { opt: opt as string | undefined }
3. 使用Object.assign
和对象展开逻辑类似,通过Object.assign动态合并属性:
const bar: Foo = Object.assign({}, opt !== undefined ? { opt } : {})
内容的提问来源于stack exchange,提问作者Colm Bhandal
相关产品推荐
相关产品推荐

