编程后端开发者 / TypeScript架构师

在TypeScript中如何实现和使用包装类型(Wrapper types)?在使用原始类型及其包装类型时会出现什么问题?

用 Hintsage AI 助手通过面试

答案

TypeScript区分原始类型(stringnumberboolean)及其对象包装类型(StringNumberBoolean)。包装是通过构造函数创建的对象:

const primitive: string = 'hello'; const wrapper: String = new String('hello');
  • 原始类型 — 简单,有效,除了内置的没有方法和属性。
  • 对象包装 — 具有相应方法/属性的对象,在业务逻辑中很少使用。
  • 在比较时primitive === wrapper的结果为false
console.log('hello' === new String('hello')); // false
  • 在类型化时应始终使用原始类型(string而不是String)。
  • 只有在需要与generic-API库交互时(例如用于反射或元编程),才使用包装类型。

有陷阱的问题

如果值是原始类型,是否可以在TypeScript接口中使用包装类型(StringNumberBoolean)?

答案: 不建议使用包装:在大多数情况下,值将是原始类型,而直接从包装类型继承接口将导致错误。最好始终使用stringnumberboolean

由于不懂该主题的细微差别而导致的真实错误示例


故事

在一个用于存储姓名的Web应用程序中,在用户接口中使用了String类型。这导致了比较错误和单元测试失败,这些测试要求类型完全相同(原始类型和它们的包装类型在标识上是不同的)。


故事

一个库开发者通过Number对generic函数进行了类型化,库的客户传入了原始值,导致了类型保护方法未意外针对原始类型生效的问题。产生了一个难以调试的类型转换错误。


故事

在一个分析服务中,使用了Boolean类型作为用户活动标志,且在数据过滤中的比较结果始终为false,尽管视觉值一致。导致数据处理不正确及报告崩溃。