首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

在Typescript中使用"as const“而不添加"readonly”修饰符?

在 TypeScript 中,as const 是一个类型断言,它用于创建一个只读的、不可变的值。当你将一个对象或数组使用 as const 断言时,TypeScript 会为该对象或数组生成一个最具体的类型,其中所有的属性都是只读的,并且属性的类型也是最具体的(例如,字符串字面量类型而不是字符串类型)。

基础概念

  • 类型断言:TypeScript 中的一种机制,允许开发者指定一个值的类型。
  • 只读属性:使用 readonly 关键字标记的属性,表示该属性的值在初始化后不能被修改。

使用 as const 的优势

  1. 不可变性:确保对象或数组一旦创建就不能被修改,这有助于编写更安全的代码。
  2. 类型安全as const 会生成更具体的类型,有助于在编译时捕获潜在的错误。
  3. 性能优化:不可变数据结构有时可以被 JavaScript 引擎更有效地处理。

类型与应用场景

  • 对象:当你想要一个所有属性都是只读的对象时。
  • 数组:当你想要一个不可变的数组时。
  • 枚举值:当你想要一个不可变的枚举值集合时。

示例代码

代码语言:txt
复制
// 使用 as const 断言的对象
const config = {
  apiUrl: "https://example.com/api",
  timeout: 5000,
} as const;

// 使用 as const 断言的数组
const colors = ["red", "green", "blue"] as const;

// 使用 as const 断言的枚举值
const Status = {
  Active: "active",
  Inactive: "inactive",
} as const;

遇到的问题及解决方法

问题:为什么即使使用了 as const,属性仍然可以被修改?

这通常是因为 TypeScript 的类型系统是结构化的,而不是名义化的。这意味着只要两个类型的结构相同,它们就被认为是兼容的。因此,即使你使用了 as const,如果另一个对象的结构与之匹配,TypeScript 可能不会阻止你修改属性。

解决方法:

确保你没有通过类型断言或其他方式绕过 as const 的限制。如果你需要确保属性不可修改,可以考虑使用 readonly 关键字:

代码语言:txt
复制
interface ReadonlyConfig {
  readonly apiUrl: string;
  readonly timeout: number;
}

const config: ReadonlyConfig = {
  apiUrl: "https://example.com/api",
  timeout: 5000,
};

// 下面的代码将会报错,因为 apiUrl 是只读的
// config.apiUrl = "https://another-example.com/api";

总结

as const 是一个强大的工具,用于创建不可变的值和类型安全的代码。它适用于需要确保数据不被意外修改的场景。如果你发现即使使用了 as const 属性仍然可以被修改,检查是否有其他代码绕过了这个限制,或者考虑使用 readonly 关键字来增强类型安全。

页面内容是否对你有帮助?
有帮助
没帮助

相关·内容

TypeScript 5.0 现已发布:全新的装饰器,速度、内存和包大小优化

从构造函数推断类属性 TypeScript 5.0 引入了将 const 修饰符添加至类型参数声明的功能,也就是默认做 const-like 推断。...这项功能非常适合那些需要具体类型,而 TypeScript 已经推断出较通用类型的场景。以往,为了实现 const-like 推断,开发者需要在某些位置添加“as const”。...Const 修饰符会影响调用中编写的对象、数组和原始表达式的推断,但不会拒绝可变值、或者说需要不可变约束。因此,开发者必须牢记 const 修饰符的行为以确保正确使用。...在 TypeScript 5.0 之前,arg.names 的推断类型为 string[],但如果我们需要的是 readonly string[],则需要在调用函数时使用 as const 进行断言。...而在 TypeScript 5.0 中,我们可以将 const 修饰符添加至类型参数声明当中,借此默认进行 const-like 推断。

96510

【TS】1294- 搞懂 TypeScript 中的映射类型(Mapped Types)

在我们实际开发中,经常会需要一个类型的所有属性转换为可选类型,这时候你可以直接使用 TypeScript 中的 Partial工具类型: type User = { name: string;...Type '"name"' is not assignable to type 'User2'. */ 四、映射修饰符的应用 在自定义映射类型的时候,我们可以使用两个映射类型的修饰符来实现我们的需求...修饰符:将指定属性设置为可选类型; 前面介绍 Readonly和 Partial工具类型的时候已经使用到: type Readonly = { readonly [P in keyof T]:...: T[P] | undefined; } 当然,也可以对修饰符进行操作: +添加修饰符(默认使用); -删除修饰符; 比如: type Required = { [P in keyof...修饰符 }; 也可以放在前面使用: type NoReadonly = { -readonly [P in keyof T]: T[P]; // 通过 - 删除 readonly 修饰符 }

2.4K10
  • TypeScript 5.0 正式发布!

    到目前为止,通常不得不在某些地方添加const,以实现所需的推断: // 我们想要的类型: readonly ["Alice", "Bob", "Eve"] // 我们得到的类型: string[] const...在 TypeScript 5.0 中,可以在类型参数声明中添加const修饰符,从而使类const推断成为默认值: type HasNames = { names: readonly string[]...; // T 是 readonly ["a", "b", "c"] fnGood(["a", "b" ,"c"]); 同样,要记住,const修饰符只影响在调用中编写的对象、数组和基本类型表达式的推断...这些条件将添加到解析器默认使用的现有条件中。..., 123); // ❌ 编辑器中不区分大小写的导入排序 在 Visual Studio 和 VS Code 等编辑器中,TypeScript 支持组织和排序导入和导出的体验。

    3.9K70

    【TypeScript 演化史 — 第二章】基于控制流的类型分析 和 只读属性

    严格的 Null 检查 当与可空类型一起使用时,基于控制流的类型分析尤其有用,可空类型使用包括 null 或undefined 在联合类型中的表示。...在严格的 null 检查模式下,undefined 的类型会自动添加到可选属性的联合类型中,因此我们不必显式将其写出。 明确赋值分析 基于控制流的另一个新特性是明确赋值分析。...其思想是确保每个不可空的局部变量在使用之前都已正确初始化。 只读属性 在 TypeScript 2.0 中,readonly 修饰符被添加到语言中。...修饰符应用于类中声明的属性。..., ]; // Error: 类型 “ReadonlyArray” 中的索引签名仅允许读取 primesBelow10[] = ; 只读与不变性 readonly 修饰符是TypeScript

    2K10

    这 5 个 TypeScript 的功能特征,你需要熟悉下

    有时,由于没有使用正确的 TypeScript 功能并且没有遵循其最佳实践,可能会出现大量代码重复和样板。 在本文中,我们将研究 TypeScript 可以赋予我们的五个最重要的功能。...让我们创建一个方法来将任何定义的类型添加到数组中: function addItem(item: string, array: string[]) { array = [...array, item...通过简单地使用泛型,我们可以重用代码而不是添加更多样板: function addItem(item: T, array: T[]) { array = [...array, item];...在这种情况下,它用于删除 readonly 修饰符。它可用于从属性中删除其他修饰符,例如 ?。 5、类型保护 类型保护是一组帮助我们缩小对象类型的工具。...最后的想法 在本文中,我们只是探讨了我们可以使用的最重要的 Typescript 功能。由于这只是一个概述,我们只是触及了它们的表面。 我的目标是让你好奇并展示 Typescript 的能力。

    1.3K40

    【TypeScript 演化史 — 第七章】映射类型和更好的字面量类型推断

    使用映射类型,可以捕获类型系统中类似 Object.freeze() 等方法的效果。冻结对象后,就不能再添加、更改或删除其中的属性。...除了 Point 类型之外,还必须定义 FrozenPoint 类型,这样才能将 readonly 修饰符添加到两个属性中。...更多映射类型的示例 上面已经看到 lib.d.ts 文件中内置的 Readonly 类型。此外,TypeScript 定义了其他映射类型,这些映射类型在各种情况下都非常有用。...在 TypeScript 2.0 中,类型系统扩展了几个新的字面量类型: boolean 字面量类型 数字字面量 枚举字面量 不带类型注解的 const 变量或 readonly 属性的类型推断为字面量初始化的类型...readonly 修饰符只限制从 TypeScript 代码中对属性的访问,在运行时就无能为力。也就是说,它会被编译时删除掉,不会出现在生成的 JS 代码中。

    3.8K40

    【TypeScript 演化史 -- 7】映射类型和更好的字面量类型推断

    使用映射类型,可以捕获类型系统中类似 Object.freeze() 等方法的效果。冻结对象后,就不能再添加、更改或删除其中的属性。...除了 Point 类型之外,还必须定义 FrozenPoint 类型,这样才能将 readonly 修饰符添加到两个属性中。...在方括号中,使用了 keyof 操作符。keyof T 将 T 类型的所有属性名表示为字符串字面量类型的联合。 方括号中的 in 关键字表示我们正在处理映射类型。...在 TypeScript 2.0 中,类型系统扩展了几个新的字面量类型: boolean 字面量类型 数字字面量 枚举字面量 不带类型注解的 const 变量或 readonly 属性的类型推断为字面量初始化的类型...readonly 修饰符只限制从 TypeScript 代码中对属性的访问,在运行时就无能为力。也就是说,它会被编译时删除掉,不会出现在生成的 JS 代码中。

    2.9K10

    TypeScript

    target为“es5”时,const h: symbol = Symbol();会报错,因为es5标准中没有Symbol,解决方法,在tsconfig.json中的lib添加["ES2015"],同理...console.log在浏览器当中是BOM所提供的,而在TypeScript中把BOM 和DOM都归结到DOM一个标准库中,所以lib中需要追加["DOM"] image.png image.png...类型 // 方式二 const num2 = res; //断言为number,JSX下不能使用 十六、TypeScript 接口 export {}; //确保和其他示例中没有成员冲突...//可以使用静态方法 console.log(jack.name); 二十、TypeScript 类的只读属性 readonly 当readonly 和访问修饰符同时存在,readonly 写在访问修饰符的后面...protected readonly gender: boolean; //只能在子类成员中访问 并且只读不能修改 二十一、TypeScript 类与接口 使用 implements 关键字 //

    1.8K41

    TypeScript 官方手册翻译计划【五】:对象类型

    项目地址:TypeScript-Doc-Zh,如果对你有帮助,可以点一个 star ~ 本章节官方文档地址:Object Types 对象类型 在 JavaScript 中,最基础的分组和传递数据的方式就是使用对象...在 TypeScript 中,我们则通过对象类型来表示。...只读属性 在 TypeScript 中,我们可以将属性标记为 readonly,表示这是一个只读属性。虽然这不会改变运行时的任何行为,但标记为 readonly 的属性在类型检查期间无法再被重写。...在使用 TypeScript 进行开发的过程中,它可以有效地表明一个对象应该如何被使用。...function doSomething(pair: readonly [string, number]) { // ... } 在 TypeScript 中无法重写只读元组的任何属性。

    1.8K30

    杀手级的TypeScript功能:const断言

    const 断言 1const x = { text: "hello" } as const; 官方文档中给出了这样的解释: TypeScript 3.4 引入了一个名为 const 断言的字面值的新构造...用新的 const 功能,我可以这样做: 1let y = 'x' as const; // y has type 'x'` 对象字面量获取只读属性 在 Typescript 3.4 之前,类型扩展发生在对象字面量中...: number }; 你会注意到从 setCount 推断的类型已经在每个属性中附加了 readonly 修饰符,正如文档的项目符号所述。...这就是所发生的事情: 1{ 2 readonly type: "SET_COUNT"; 3 readonly payload: number 4}; action 中的每个字面量都被添加了 readonly...数组字面量成为只读元组 在 TypeScript 3.4 之前,声明一个字面量数组将被扩展并且可以修改。 使用 const,我们可以将字面量锁定为其显式值,也不允许修改。

    1.2K10

    TypeScript 3.4 正式发布!

    4} 只读元组:对 readonly 元组的新支持。我们可以用 readonly 关键字为任何元组类型添加前缀,使其成为 readonly 元组,就像用数组的简写语法一样。...readonly 映射类型修饰符和 readonly数组:会自动把类数组类型转换为相应的 readonly 对应项。 const断言—— 为字面量引入一个名为 const 断言的新构造。...当你使用 const 断言构造新的表达式时,可以给语言发出下面这些信号: 该表达式中的字面量类型不应被加宽(例如,不要从 “hello” 到 string) object 字面量获得 readonly...globalThis 提供了一种访问全局范围的标准方法,可以在不同环境中使用。 将参数转换为解构对象—— 实现了一个新的重构,将现有函数转换为使用此“命名参数”模式。...在存在多个参数的情况下,TypeScript 将提供重构以将参数列表转换为单个解构对象。 可以到官方发布说明了解有关 TypeScript 3.4 所有新功能的更多信息。

    1.4K10

    15个Typescript 5.0 中重要的新功能快速了解一下

    ,则必须为其添加 as const: // string[] const a = ["Alice", "Bob", "Eve"] // readonly ["Alice", "Bob", "Eve"]...const b = ["Alice", "Bob", "Eve"] as const TypeScript 5.0 允许您将 const 修饰符添加到类型参数声明中: declare function..."a", "b" ,"c"]); 但请记住,const 修饰符仅影响在调用中编写的对象、数组和原始表达式的推断,因此不会(或不能)用 as const 修改的参数将看不到任何 行为改变: declare...所有枚举都是联合枚举 在 TypeScript 5.0 中,所有枚举现在都被视为联合枚举。 联合枚举为使用枚举值提供了更好的类型安全性和改进的人体工程学。...--inlineSourceMap:在发出的 JavaScript 中包含源映射文件。 12. 编辑器中不区分大小写的导入排序 TypeScript 5.0 通过不区分大小写改进了编辑器中的导入排序。

    29030

    你应该知道的TypeScript高级概念

    那这种情况下我们可以使用readonly这样一个关键词,去修饰一下这里的summary。那添加了readonly过后我们这个summary他在初始化完成过后就不能够再去修改了。...而在TypeScript中,我们除了可以使用所有ECMAScript的标准当中所有类的功能,他还添加了一些额外的功能和用法,例如我们对类成员有特殊的访问修饰符,还有一些抽象类的概念。...中我们需要明确在类型中取声明他所拥有的一些属性,而不是直接在构造函数当中动态通过this去添加。...类的访问修饰符 接下来我们再来看几个TypeScript中类的一些特殊用法,那首先就是类当中成员的访问修饰符,类中的每一个成员都可以使用访问修饰符去修饰他们。...,说的就是受保护的,我们可以添加一个gender的属性,他的访问修饰符我们就使用protected,我们同样在构造函数中初始化一下gender。

    50610

    深入学习下 TypeScript 中的泛型

    在一个字段中传递 true 意味着您希望它被返回,而 false 则意味着您希望它被省略。...这里引用的Readonly的实现只是为了说明的目的。 请注意修饰符 readonly,它作为前缀添加到此代码中的 [K in keyof T] 部分。...目前,可以在映射类型中使用的两个可用修饰符是 readonly 修饰符,它必须作为前缀添加到属性,以及 ? 修饰符,可以作为属性的后缀添加。这 ?修饰符将字段标记为可选。...两个修饰符都可以接收一个特殊的前缀来指定是否应该删除修饰符 (-) 或添加 (+)。如果仅提供修饰符,则假定为 +。...TypeScript 仅适用于类型,因此请确保始终将类型声明中的标识符读取为类型,而不是值。在此代码中,您使用每个布尔值的确切类型,true 和 false。

    39K30

    编写TypeScript工具类型,你需要知道的知识

    由于 friend 成员是对象,上面的 Partial 处理只对第一层添加可选修饰符,假如需要将对象成员内的成员也添加可选修饰符,可以使用 Partial 递归来解决。...如果选择为 id 字段提供添加可选修饰符的话,那就太不明智了。因为在删除用户时,即使不填写 id 属性也不会报错,这不是我们想要的结果。...在 JavaScript 中,对象可以用属性名获取值,而在 TypeScript 中,这一切被抽象化,变成通过索引获取类型。...TypeScript 提供了从旧类型中创建新类型的一种方式 。在映射类型里,新类型以相同的形式去转换旧类型里每个属性。...文章开头的 Partial 工具类型正是使用这种搭配,为原有的类型添加可选修饰符。 条件类型 语法: T extends U ?

    1.4K50

    深入学习下 TypeScript 中的泛型

    在一个字段中传递 true 意味着您希望它被返回,而 false 则意味着您希望它被省略。...这里引用的Readonly的实现只是为了说明的目的。请注意修饰符 readonly,它作为前缀添加到此代码中的 [K in keyof T] 部分。...目前,可以在映射类型中使用的两个可用修饰符是 readonly 修饰符,它必须作为前缀添加到属性,以及 ? 修饰符,可以作为属性的后缀添加。这 ?修饰符将字段标记为可选。...两个修饰符都可以接收一个特殊的前缀来指定是否应该删除修饰符 (-) 或添加 (+)。如果仅提供修饰符,则假定为 +。...TypeScript 仅适用于类型,因此请确保始终将类型声明中的标识符读取为类型,而不是值。在此代码中,您使用每个布尔值的确切类型,true 和 false。

    17810
    领券