# 区别
# any和unkown的区别
- any表示任意类型,可以被任何类型分配(赋值),也可以分配给任何类型
- unkwon表示位置类型,可以被任何类型分配(赋值),不能分配给任何类型 首先看any
// 1. 把any类型分配给其他类型
let val:any;
let val_any: any = val;
let val_unknown = val;
let val_void: void = val;
let val_undefined: undefined = val;
let val_null: null = val;
let val_string:string = val;
let val_boolean:boolean = val;
// 报错:不能将类型“any”分配给类型“never”
// let val_never:never = val;
// 2. 把其他类型分配给any
val = '';
val = 1;
val = true;
val = null;
val = undefined;
// 报错:“unknown”仅表示类型,但在此处却作为值使用
// val = unknown;
// 报错:“never”仅表示类型,但在此处却作为值使用
// val = never;
// 报错:“any”仅表示类型,但在此处却作为值使用
// val = any;
// 报错:应为表达式
// val = void;
然后unknow类型
// 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等有限操作
# 数组和元组的区别
- 如果数组的类型在[]前面,那么表示该数组全都是该类型
- 如果数组的类型在[]内部(严格限制类型和长度的元组),那么表示该数组的第x个元素是该类型
首先,数组的类型在[]前面
// 此时表示数组内部都是数字类型
// let arr:number[] = [1,2,3]
let arr:(number | string)[] = ['s', 2, 'a'];
let arr: any[] = ['a', 2, true]
在看数组的类型在[]内部的用法,此时就是元组
// 报错:不能将类型"[number, number, number]"分配给类型"[number]".源具有3个元素,但目标仅允许1个
// let arr:[number] = [2,3, 4]
let arr: [number] = [2]; // 这个时候才是对的
// 表示多种类型的数组,但是严格限制长度和类型必须对照
let arr:[string, number] = ['a', 1];
// 报错:不能将类型string分配给类型number
// let arr:[string, number]= [1, 'd'];
// any元素也需要规定元素数量
let arr:[any, any, any] = ['s', 2, true ]
- 其实[string, boolead]这种声明形式指的是元组,也就是一个一直元素数量和类型的数组
# 索引签名和工具类型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是属性值的类型
# interface和type区别
如果在开发一个包或者要被继承,那么使用接口interface
如果定义基础类型或者进行类型运算,那么使用类型别名type
不同点1:interface可以进行声明合并,type不可以
// 1.interface同名接口会自动进行声明合并 interface union{ name:string; } interface union{ age:number; } let u = {} as union; // undefined console.log(u.name); // undefined console.log(u.age); // 但是使用其他属性,不会undefined,会报错:类型“union”上不存在属性“list” console.log(u.list); // 2.type类型别名不可以进行声明合并 // 报错:标识符“type_a”重复 // type type_a = number; // type type_a = string;不同点2:type可以进行赋值运算,interface不可以,必须先继承
// 1.type可以进行类型运算(只能把type赋值给type,不能把type赋值给其他类型变量) type type_a = number; type type_sum = type_a | string; // 2. interface不可以,必须要通过继承 interface inf_a{ name:string; } // “inf_a”仅表示类型,但在此处却作为值使用 // interface inf_a = inf_a; // 正确做法是 interface inf_b extends inf_a{ age:number; } let inf = {} as inf_b; // undefined undefined console.log(inf.age,inf.name);不同点3: interface只可以用于对象和函数;type则可以用于对象,函数,基础类型,数组,元组
// 1. 接口 // 对象 interface obj { name: string } // 函数 interface func { (x: string): number; } // 2. 类型别名type // 对象 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]
# enum 和const emum
- enum可以进行反向查找,所以遍历得到的长度是预计长度的两倍
- const enum不可以进行反向查找,所以得到的是预计长度
// 1. enum
enum REVERSE {
OK,
NO
}
//0
console.log(REVERSE.OK)
// OK
console.log(REVERSE[0]);
// NO
console.log(REVERSE[1]);
// undefined,虽然是undefined,但是不会报错!
console.log(REVERSE[10]);
// 遍历,得到枚举的值和反向查找的值
// of不可以,警告需要[Symbol.interator]方法
for(let item in REVERSE) {
// 0 1 OK NO
console.log(item)
}
// 2. const enum
const enum ONE {
OK,
NO
}
console.log(ONE.OK);
// 报错:只有使用字符串文本才能访问常数枚举成员。
// console.log(ONE[0]);
// 遍历
// 报错:"const" 枚举仅可在属性、索引访问表达式、导入声明的右侧、导出分配或类型查询中使用。
/* for(let item in ONE){
} */
# 应用
# 类型键入
type User = {
outer: string;
// 内部使用一个数组
innerList: {
innerName: string
}[]
}
// [property] outer:string
type userOut = User['outer']