1.any和unknow的区别:
主要区别:
unknown和any都是TS中的顶级类型,但主要区别在于:使用any相当于彻底放弃了类型检查,而unknown类型相较于any更加严格,在执行大多数操作之前,会进行某种形式的检查。
const any:foo = 123
console.log(foo.msg) // 符合ts的语法
const a : unknown = foo // ok
const b : any = foo // ok
const c : string = foo // ok
const bar : unknown = 222
console.log(bar.msg) // 报错
const a : unknown = bar // ok
const b : any = bar // ok
const c : string = bar // 报错
foo是any类型,任何操作都是没有类型检查的,因此对其进行任意类型的赋值都是合法的
bar是unknown类型,因此不能确定是否有msg属性,不能通过语法检查,同时unknown类型的值也不能赋值给any和unknown以外的类型变量
联合类型和交叉类型:
在联合类型中,unknown类型会吸收任何类型。即如果任一组成类型是unknown,联合类型也会相当于unknown
type UnionType1 = unknown | null; // unknown
type UnionType2 = unknown | undefined; // unknown
type UnionType3 = unknown | string; // unknown
type UnionType4 = unknown | number[]; // unknown
而any更是能吸收unknown类型,如果任一组成类型是any,则联合类型相当于any
UnionType5 = unknown | any; // any
由于每种类型都可以赋值给unknown类型,所以在交叉类型中包含unknown不会改变结果。
type IntersectionType1 = unknown & null; // null
type IntersectionType2 = unknown & undefined; // undefined
type IntersectionType3 = unknown & string; // string
type IntersectionType4 = unknown & number[]; // number[]
type IntersectionType5 = unknown & any; // any
用法:
优先使用unknown,尽量避免any的使用,unknown一般用来接收暂时不知道类型的变量(如接口返回的数据)
const a : unknown = await ajax.get('/api/users')
const b = a as number(类型断言)
2.什么是never类型:
如果把any看作是全集,unknown看作是未知集,那么never就是空集
如type A: string & number, 此时A的类型即为never
never的使用:
type A = string | number | boolean;
const a : A = ('hello' as any);
if (typeof a === 'string') {
a.split('')
}else if ( typeof a === 'number') {
a.toFixed(2)
}else if ( typeof a === 'boolean') {
a.valueOf()
}else {
a.toString() // 此时a即为never,对a.的任何操作都会报错
console.log('没了')
}
3.enum的使用
写法:
//默认从0开始,赋值后往后依此类推
enum Direction{
Up,
Down,
Left,
Right,
}
console.log(Direction.Up)//0
console.log(Direction[0])//Up
何时使用enum:
一般用于前后端两组数据之间的映射
还可用于前端权限控制
enum Permission {
None = 0, // 0000
Read = 1 << 0, // 0001
Write = 1 << 1, // 0010
Delete = 1 << 2, // 0100
Manage = Read | Write | Delete, // 0111
}
type User = {
permission:Permission
}
const user: User = {
permission:0b0101 // 0b代表二进制
}
if ((user.permission & Permission.Write) === Permission.Write) {
console.log('拥有写权限')
}
if ((user.permission & Permission.Manage) === Permission.Manage) {
console.log('拥有管理权限')
}
何时不用enum :
一般只有number枚举时才会使用enum,string或者string和number混用时枚举时不使用enum