1.any和unkown的区别
any表示任意类型,
可以被任何类型分配,也可以分配给任何类型
unkwon表示未知类型,
可以被任何类型分配,不能分配给任何类型
首先看any类型
// 1. 把any类型分配给其他类型
let val:any
let val_any:any = val
let val_unknown:unknown = val
let val_void:void = val
let val_undefined:undefined = val
let val_null:null = val
let val_number:number = val
let val_string:string = val
let val_boolean:boolean = val
// 报错:不能将类型“any”分配给类型“never”
// let val_never:never = val
// 2.把其他类型分配给1any
val = ''
val = 1
val = true
val = null
val = undefined
// 报错:“unknown”仅表示类型,但在此处却作为值使用
// val = unknown
// 报错:“never”仅表示类型,但在此处却作为值使用
// val = never
// 报错:“any”仅表示类型,但在此处却作为值使用
// val = any
// 报错:应为表达式
// val = void
然后看看unknown类型
// 1.把unknown类型分配给其他类型
let val: unknown
let val_any:any = val
let val__unknown:unknown = val
// 报错:不能将类型“unknown”分配给类型“string”
let val_string:string = val
// 报错:不能将类型“unknown”分配给类型“number”
let val_number:number = val
// 报错:不能将类型“unknown”分配给类型“boolean”
let val_boolean:boolean = val
// 报错:不能将类型“unknown”分配给类型“null”
let val_null:null = val
// 报错:不能将类型“unknown”分配给类型“undefined”
let val_undefined:undefined = val
// 2.把其他类型分配给unknown类型
val = ''
val = 0
val = true
val = undefined
val = null
// 和any一样,报错
val = void
val = any
val = unknown
val = never
代码规范,any虽然可以代表任意类型,但是能不用就不要用,这是默认的代码规范问题,不要用成anyscript!
与any任意类型相比,因为unknown是未知类型,所以只能进行!!,!,?,typeof,instanceof等有限操作
2. 数组和元组的区别
如果数组的类型在[]前面,那么表示该数组全部都是该类型
如果数组的类型在[]内部(严格限制类型和长度的元组),那么表示该数组的第x个元素是该类型
首先,数组的类型在[]前面
let arr:(number | string)[] = ['s',3,'a'];
let arr:any[] = ['a',2,true];
此时来看看数组的类型在[]内部的用法,此时就是元组
!
let arr:[number] = [2];
let arr:[string,number] = ['a',1];
let arr:[any,any,any] = ['s',2,true];
其实[string,boolean]这种声明形式指的是元组,也就是一个已知元素数量和类型的数组
3.索引签名和工具类型Record的区别
其实Record工具类型的本质就是索引签名,不同之处只是用法,仅仅需要继承就可以了,不需要再写一遍索引签名的用法
interface inf{
name:string;
age:number;
[k:string]:any;
let obj:inf = {
name:'yiye',
age:33,
city:'foshan'
Record工具类型的用法(ts内置的工具类型)
interface inf extends Record<string,any>{
name:string;
age:number;
let obj:inf = {
name:'yiye',
age:33,
city:'foshan'
Record工具类型的.d.ts声明文件源码是:
type Record<K extends keyof any, T> = {
[P in K]: T;
所以用法就是继承这个工具类型,然后泛型参数1是属性类型,参数2是属性值的类型
4.interface和type的区别
如果在开发一个包或者要被继承,那么使用接口interface
如果要定义基础数据类型或者进行类型运算,那么使用类型别名type
不同点1:interface可以进行声明合并,type不可以
interface union{
name:string;
interface union{
age:number;
let u = {} as union;
console.log(u.name);
console.log(u.age);
console.log(u.list);
不同点2:type可以直接进行赋值运算,而interface不可以,必须先继承
type type_a = number;
type type_sum = type_a | string;
interface inf_a{
name:string;
interface inf_b extends inf_a{
age:number;
let inf = {} as inf_b;
console.log(inf.age,inf.name);
不同点3:interface只可以用于对象和函数;type则可以用于对象,函数,基础类型,数组,元组
interface obj{
name:string;
interface func{
(x:string): number;
type type_obj = {name:string};
type type_func = (x:string) => string
type type_boolean = true;
type type_null = null;
type type_union = string | number;
type type_arr = number[];
type type_tuple = [number,string];
5.enum和const enum
enum可以进行反向查找,所以遍历得到的长度是预计长度的两倍
const enum不可以进行反向查找,所以得到的是预计长度
enum REVERSE{
console.log(REVERSE.OK)
console.log(REVERSE[0])
console.log(REVERSE[1])
console.log(REVERSE[10])
for(let item in REVERSE){
console.log(item);
const enum ONE{
console.log(ONE.OK)