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

TypeScript中Readonly<T>对原始类型失效的原因及解决方法问询

为什么TypeScript的Readonly工具类型仅对非原始类型生效?是否有办法让它也作用于原始类型?

原因解析

Readonly的核心作用是将对象类型的所有属性标记为只读,它对原始类型(string、number、boolean等)无效,本质是两个层面的原因:

  1. 原始类型的特性:原始类型是值类型,变量直接存储实际值,不存在可被修改的“属性”。Readonly的实现逻辑是遍历对象的属性并添加readonly修饰符,对没有属性的原始类型来说,Readonly<T>完全等价于T本身,自然不会有任何限制效果。
  2. 操作的本质差异:你代码里对原始类型变量的str = "New string"是变量重新赋值,而对象类型的obj.str = "New string"是修改对象属性。Readonly只限制后者,不影响变量本身的赋值行为。

解决办法:使用const参数

如果想让原始类型的参数无法被重新赋值,可以借助TypeScript 5.0及以上版本支持的const参数特性,将函数参数声明为const val: T。这样在函数内部,不管是原始类型还是对象类型的参数,都无法被重新赋值,同时对象的属性也会被限制为只读:

function inspect<T>(inspector: (val: const T) => void): void {
  // 执行某些操作...
}

function run() {
  inspect<string>((str) => {
    str = `New string` // 编译错误:无法为 'str' 赋值,因为它是只读参数
  })

  inspect<number>((num) => {
    num = 12 // 编译错误
  })

  inspect<boolean>((bool) => {
    bool = true // 编译错误
  })

  inspect<{str: string, num: number, bool: boolean}>((obj) => {
    obj.str = `New string` // 编译错误
    obj.num = 12 // 编译错误
    obj.bool = true // 编译错误
  })
}

需要注意的是,const参数限制的是参数变量本身的可赋值性,和Readonly限制对象属性的逻辑互补,两者结合能实现对所有类型参数的只读限制。

内容的提问来源于stack exchange,提问作者Riccardo Perego

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.14 17:03:18