关于类型注解,我们前面已经学过基本的类型注解、联合类型、类型推断、自定义类型,其实还有一些更高级的知识,我们可以了解一下。
理解类型:
在 TS
中,我们可以将类型看成是一个“存放一系列值的集合”,比如:
number
类型可以看成一个包含所有数值型数据的集合,如:1、9999、23.5、……
string
类型可以看成所有字符串数据组成的集合,如:'你好'、'二狗子'、 '如花'、……
boolean
类型可以看成由 true
和 false
组成的集合。
interface Human {
name: string,
age: number
}
Human
类型可以看成是由所有“含有name
和age
属性,且name
属性的值是string
类型、age
属性的值是number
交叉类型:
类型可以理解一个“存放一系列值的集合”,当然可以像集合一样进行运算,比如我们前面学的联合类型,就可以理解成进行了并集运算。而交叉类型刚好和联合类型相反,用 &
操作符表示,可以理解成求交集。效果是把多个类型合并成一种新的类型。
interface A {
name: string,
age: number
}
interface B {
sex: number
}
// A类型和B类型进行交叉运算,其实得到一个新的类型,类似于这样的结构:
// {
// name: string,
// age: number,
// sex: string
// }
let obj: (A & B)
// obj 必须符合A类型的特点,同时也要符合B类型的特点
obj = {
name: '如花',
age: 18,
sex: '男'
}
类型别名用来给一个类型起个新名字,它只是起了一个新名字,并没有创建新类型。
// 起个别名叫T1
type T1 = { name: string, age: number }
let o1: T1 = {
name: '如花',
age: 18
}
interface A {
name: string,
age: number
}
interface B {
sex: string
}
// 为 A & B 类型起个新名字(仅仅是起了个新名字)
type MyNewType = A & B
let obj: MyNewType
obj = {
name: '如花',
age: 18,
sex: '男'
}
// 为 string | number 联合类型起个新名字
type t1 = string | number
let v1: t1
v1 = '二狗子'
v1 = 100
// 下面的会报错
v1 = false
附:类型别名和接口的区别?
请参考文章:
https://blog.csdn.net/sinat_37255207/article/details/124906155
https://www.jb51.net/article/163299.htm
https://segmentfault.com/a/1190000038825361
keyof
操作符:
通过 keyof
操作符可以获取一个类型中的所有键组成的联合类型。
type o1 = {
name: '如花',
age: 18,
sex: '男'
}
// keyof o1 的结果相当于 'name' | 'age' | 'sex'
type kt = keyof o1
let v1: kt
v1 = 'name'
v1 = 'age'
v1 = 'sex'
// 下面的会报错
v1 = 'xxx'
keyof
操作符会获取一个类型的所有键,并用这些获得的值组成一个联合类型的类型
当 TS
无法确定变量的类型或者 TS
类型推断的结果不能满足我们的要求的时候,我们可以使用类型断言,用我们自己的类型判断去覆盖 TS
的类型判断。意思就是:在这个地方“我们比TS
”编译器更了解自己的代码。
let o1 = {}
// 这里会报错,因为TS编译器认为o1对象没有name属性
o1.name = '如花'
TS
的判断。let o1 = {}
// 我们定义一个新类型 mt
type mt = { name: string }
// 在这里告诉TS编译器,o1的类型是mt类型 (写法1)
(<mt>o1).name = '如花'
// 这是类型断言的另一种写法
(o1 as mt).name = '如花'
console.log(o1);
值 as 类型
和
<类型>值