typescript学习-字面量类型

101 阅读3分钟

1.场景

let param = 'Get'
function func(param:'Get'){
  console.log(param)
}
func(param)

出现的错误如下:

image.png

上述错误,在长期使用js,刚开始接触ts,其实是很容易遇到的。疑惑点在于,定义了一个string类型的变量param,赋值为Get,为何不能传参到函数func中。其实func接收的参数类型和param的参数类型完全就是2类。

2.const定义的类型区别

定义代码如下:

let param_1 = 'Get'
const param_2 = 'Get'

上述代码,在js中,它们都是一个类型,即string类型,只不过一个是常量,一个是非常量。但在ts中,它们是2个类型,一个是string类型,一个是Get类型,其中这个Get类型是一个字面量类型,表示这个变量的值,只能是Get,但string类型不一样,还可以赋值为其他类型。也许这很难理解,但你看过一下的代码,就可能要容易理解一些:

let param:'Param' = 'Param'
let param_1:true = true
let param_2:{
  counter:1
} = {
  counter:1
}

即一个具体的值,也是可以作为一个类型来进行定义的,当使用一个具体值来定义类型时,被定义的变量只能等于这个值,这个就是字面量类型。细心一些可以发现,此时定义并没有使用const修饰符。使用const修饰符进行定义,最终得到的不仅仅是一个字面量类型,而且还是一个常量类型,即不可以进行引用修改(即赋值修改)

3.使用const进行定义对象

使用const定义一个对象,最终得到的是一个常量,但不是字面量类型。如下代码:

const a = {
  num:1
}

此时这个a变量的类型中,内层属性num的类型是number,而不是字面量1,因此num的值可以进行修改,单a不能进行二次赋值。这个和普通类型使用const来定义产生的是字面量类型就有一定的区别。但当使用一个对象值类定义时,则产生的是一个字面量类型。如下:

let a:{
  num:1
} = {
  num:1
}

此时变量a由于不是const定义,则可以进行赋值,但内层属性num的值永远只能是1。当使用const定义时,则常量a不能进行赋值操作。

4.如何解决类型转换问题

上述场景1中的示例,要如何解决?本质问题是在ts中,类型不一致导致的。因此只需要进行类型转换。将其他类型转换为对应的字面量类型即可。官方文档上使用as const进行类型转换,代码如下:

let param = 'Get' as const  // 此时类型是字面量类型'Get'
let param = {
  num:1
} as const  // 此时param类型中所有的属性都是字面量类型 num只能取1

5.总结

简单来说,在ts中,新增了一个字面量类型的概念,一些在js中能够使用的写法,在ts中会有诸多限制,但从长远来看,这些限制是很有必要的,能减少很多在开发中的错误。因此,作为开发者,在使用ts时要习惯提前进行类型定义,使用定义好的类型来处理这种参数不匹配的问题时,则要好处理很多。