编程前端开发者

TypeScript中可选属性(Optional Properties)机制如何运作,可能遇到哪些问题,如何避免?

用 Hintsage AI 助手通过面试

答案。

TypeScript中的可选属性用问号(?)表示在属性名之后。这意味着该属性可以在对象中存在或缺失。这在描述并非所有字段都是必需的结构时非常方便。

示例:

interface User { id: number; name?: string; } const u1: User = { id: 1 }; // OK const u2: User = { id: 2, name: '伊万' }; // OK

细微之处:

  • 可选属性不仅可以是undefined,也可以完全缺失在对象中。
  • 检查是否存在值(例如,if (user.name))不能区分undefined和缺失。
  • 常见的错误是没有考虑到属性可能是undefined,并且在没有检查的情况下访问方法/属性。

为了防止这种情况:

  • 使用undefined检查:
if (user.name !== undefined) { console.log(user.name.toUpperCase()); }
  • 可以使用可选链操作符:
console.log(user.name?.toUpperCase());

带陷阱的问题。

如果对象的接口描述为{ foo?: string },属性foo是否总是只能是字符串或undefined?能否将例如null的值赋给它?

错误答案:

  • "可选属性只能是字符串或undefined,不能是其他。"

正确答案:

  • 实际上,如果显式地赋值为null,TypeScript是允许的,但前提是类型扩展到string | null。默认情况下只有stringundefined
  • 示例:
interface A { foo?: string } let x: A = { foo: null }; // 错误!

由于不懂话题的细节而导致的实际错误示例。


故事

在一个大型项目中,部分对象来自服务器时缺少某些可选字段。程序员直接调用这些属性的方法(例如,toLowerCase()),如果字段缺失,就会导致运行时错误。为了修复这个问题,团队实施了对可选字段访问的严格检查和lint规则。


故事

在逻辑表达式中混淆了属性的存在性与其真值:if (user.email)对空字符串不生效,尽管属性已定义。出现了bug,导致某些通知未发送给用户。


故事

团队试图将null值写入可选属性,以为这是正确的。TypeScript报错,为了绕过这个问题,类型被扩展至string | null,这迫使团队重新审视与这些对象相关的整个业务逻辑。