在 TypeScript 中,as const 将对象/数组的值和属性转换为只读和字面量类型。这提供了严格的类型化:值不会被 "扩展" 为基本类型,而是保持其具体值。
示例:
const a = { status: 'success' }; // 类型: { status: string } const b = { status: 'success' } as const; // 类型: { readonly status: "success" }
优点:
缺点/特性:
问题: 如果对字符串数组使用 as const,它将是什么类型,是否可以将其作为普通的 string[] 传递?
答案: 类型将是 readonly ["a", "b", "c"],即只读约束的字面量类型的元组。这样的数组与类型 string[] 不兼容;不能直接传递到期望可变字符串数组的地方。
const arr = ['a', 'b', 'c'] as const; // readonly ["a", "b", "c"] function acceptsStrings(x: string[]) {} acceptsStrings(arr); // 错误!类型不兼容
故事
项目: 将 actionTypes 列表作为常量数组使用 as const,然后尝试将其传递到期望 string[] 的函数中。出现了类型错误,不得不通过
.slice()或者[...arr]显式转换。
故事
项目: 在 Redux 微框架中,将 action.type 的类型定义为通过 as const 的字面量。在实现 switch-case 时忘记了严格类型化,没有处理所有可能的字面量,导致没有进行 exhaustive check - 错误未显现,直到添加了新的 action。
故事
项目: 在自动生成 API 端点时,通过 as const 数组描述其键。尝试将这些键用作普通 Record<string, ...> 的索引失败,因类型不一致—不得不添加转换,或者显式使用数组中的键类型。