Typescript - as const 详细介绍

1,引入

在介绍 as const 之前,得先介绍点其他的,以便更好的理解。

1.1,只读

在 Typescript 中,readonly 表示只读,可以在 interfacetype 中标记属性

举例:对象

type Foo = {
  readonly name: string;
  readonly want: string;
};
const foo: Foo = { name: '下雪天的夏风', want: '求关注' };

// 报错:无法分配到 "name" ,因为它是只读属性。ts(2540)
foo.name = 456;

举例:数组

const arr: readonly string[] = ["a", "b", "c"];

// 报错:类型“readonly string[]”上不存在属性“push”。ts(2339)
arr.push('d')

// 报错:类型“readonly string[]”中的索引签名仅允许读取。ts(2542)
arr[1]= 'r'

readonly string[]ReadonlyArray<string> 是等价的。

1.2,元组

JavaScript 中,数组的元素可以是任意类型。而在 Typescript 中,如果数组的元素类型不一致,此时这个数组称为元祖(Tuple)

元祖类型:元素数量和类型都确定的数组。

可以理解为:既然能确定每个元素的类型,那数量也就确定了。

let x: [string, number];
x = ['hello', 10]; // ok
x = [10, 'hello']; // Error

在元祖中,不能访问越界元素,但可以通过push等方法扩展,但扩展元素的类型会使用联合类型替代。

x[0] = '你好' // ok

// 报错:长度为 "2" 的元组类型 "[string, number]" 在索引 "2" 处没有元素。ts(2493)
x[2] = 'xx'

// 报错:类型“boolean”的参数不能赋给类型“string | number”的参数。ts(2345)
x.push(true)

x.push('world') // ok

1.3,只读的元祖

下面的2种写法,因为只读的原因,二者在使用上并没有区别,都不能通过索引和方法修改。

Typescript编译是会区分:数组类型和元素类型的,下面的例子中会有介绍。

// 只读数组
const list: readonly string[] = ['a', 'b']
// 只读元祖
const list: readonly [string, string] = ['a', 'b']

as const 就是在只读的元祖类型上再次提高精度:类型精确到值

所以,as const得到是一个只读的元祖类型

2,as const

2.1,需求

对于上面的list来说,获取的数组元素的类型是string

// string
type tList = typeof list[number]

实际工作中,会遇到这样的需求:“要求某个变量的取值范围,限制某个数组范围内。”
以上面定义的 list 为例,需要一个这样的type

type tList = 'a' | 'b'

function getItem(item: tList) {}

2.2,as const 的效果

as const 就可以实现这个需求。我们对比下,注意listB的类型

// 只读元祖
const listA: readonly [string, string] = ['a', 'b']

// listB 的类型是:readonly ["a", "b"]
const listB = ['a', 'b'] as const

// string
type tListA = typeof listA[number]
// 'a' | 'b'
type tListB = typeof listB[number]

typeof listA[number]的读取顺序:typeof listA[number]

2.3,as const 的其他使用例子

1,数组解构

const arr = ['abc', 123]
const [p, q] = arr
// Property 'toUpperCase' does not exist on type 'string | number'.
// Property 'toUpperCase' does not exist on type 'number'.ts(2339)
p.toUpperCase()

可以看到,当我们能确定 pstring类型时,还是会报错。

解决办法就是as const

const arr = ['abc', 123] as const

2,扩展参数(展开语法)

Typescript 中,使用扩展参数时有2点要求,满足之一即可。

  • 扩展参数必须具有元组类型
  • 扩展参数需要传递给剩余参数

举例

const args = [1, 2];
function testArgs(a: number, b: number) {}

// 报错:扩展参数必须具有元组类型或传递给剩余参数.ts(2556)
testArgs(...args)

解决方法1

// 扩展参数必须具有元组类型
const args: [number, number] = [1, 2];
// 注意,这不是元祖类型!所以依旧会报错
const args: number[] = [1, 2];

而这个元祖类型也可以用as const 来解决

const args = [1, 2] as const;

解决方法2

// 扩展参数需要传递给剩余参数
function testArgs(...theArgs: number[]) {}

以上,如果对你有帮助,还请点个关注支持下。

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

下雪天的夏风

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值