理解 TypeScript 中的“as const”

理解 TypeScript 中的“as const”

Understanding ‘as const’ in TypeScript

在 TypeScript 中使用as const时,我们可以将对象的属性或数组的元素设置为readonly,向语言表明表达式中的类型不会被扩大(例如 from 42to
number)。

索引.ts
function sum(a: number, b: number) { return a + b; } // 👇️ const arr: readonly [3, 4] const arr = [3, 4] as const; console.log(sum(...arr)); // 👉️ 7

我们创建了一个sum2数字作为参数并返回总和的函数。

然而,我们在数组中有数字,所以我们需要一种方法来告诉 TypeScript 这个数组只能有2type 的元素 number


这是在 TypeScript 中
使用
const 断言的时候。

const 断言使我们能够告诉 TypeScript 数组的类型不会被扩大,例如 from [3, 4]to number[]

示例中的数组变为readonly元组,因此无法更改其内容,我们可以安全地在sum
函数调用中解压这两个数字。

如果您尝试更改数组的内容,则会出现错误。

索引.ts
function sum(a: number, b: number) { return a + b; } // 👇️ const arr: readonly [3, 4] const arr = [3, 4] as const; // ⛔️ ERROR: Property 'push' does not exist on type // 'readonly [3, 4]' arr.push(5);

我们使用了 const 断言,所以数组现在是一个readonly元组,其内容无法更改,并且尝试这样做会在开发过程中导致错误。

如果我们尝试在sum不使用 const 断言的情况下调用该函数,则会出现错误。

索引.ts
function sum(a: number, b: number) { return a + b; } // 👇️ const arr: readonly [3, 4] const arr = [3, 4]; // ⛔️ Error: A spread argument must either have a tuple // type or be passed to a rest parameter. console.log(sum(...arr)); // 👉️ 7

TypeScript 警告我们,没有办法知道变量的内容
在声明和

函数被调用
arr之间没有改变。sum()

当使用 const 断言时,数组变为只读元组,因此 TypeScript 可以确保其内容在声明和函数调用之间不会发生变化。

如果您不喜欢使用 TypeScript 的枚举结构,也可以使用 const 断言来替代枚举。

索引.ts
// 👇️ const Pages: {readonly home: '/'; readonly about: '/about'...} export const Pages = { home: '/', about: '/about', contacts: '/contacts', } as const;

如果您尝试更改对象的任何属性或添加新属性,您将收到错误消息。

索引.ts
// 👇️ const Pages: {readonly home: '/'; readonly about: '/about'...} export const Pages = { home: '/', about: '/about', contacts: '/contacts', } as const; // ⛔️ Error: Cannot assign to 'about', because it is // a read-only property Pages.about = 'hello'; // ⛔️ Error: Property 'test' does not exist on type ... Pages.test = 'hello';

然而,应该注意的是,const上下文不会将表达式转换为完全不可变的。

索引.ts
const arr = ['/about', '/contacts']; // 👇️ const Pages: {readonly home: '/', menu: string[]} export const Pages = { home: '/', menu: arr, } as const; // ✅ Works Pages.menu.push('/test');

menu属性引用了一个外部数组,我们可以更改其内容。

如果数组是在对象上就地定义的,我们将无法更改其内容。

索引.ts
// 👇️ const Pages: {readonly home: '/', readonly menu: string[]} export const Pages = { home: '/', menu: ['/about'], } as const; // ⛔️ Error: Property 'push' does not exist on type // 'readonly ["/about"]' Pages.menu.push('/test');

发表评论