ts问题小总结
-
作为一个前端小白,刚刚开始学习TS的时候,遇到了许多疑惑,但是对于学过后端的朋友来说可能是小问题,所以酌情阅读~
区别
1.any和unkown的区别
-
any表示任意类型,
可以被任何类型分配,也可以分配给任何类型
-
unkwon表示未知类型,
可以被任何类型分配,不能分配给任何类型
-
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;
val = '';
val = 1;
val = true;
val = null;
val = undefined;
let val: unknown;
let val_any:any = val;
let val__unknown:unknown = val;
let val_string:string = val;
let val_number:number = val;
let val_boolean:boolean = val;
let val_null:null = val;
let val_undefined:undefined = val;
val = '';
val = 0;
val = true;
val = undefined;
val = null;
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'
}
interface inf extends Record<string,any>{
name:string;
age:number;
}
let obj:inf = {
name:'yiye',
age:33,
city:'foshan'
}
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{
OK,
NO
}
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{
OK,
NO
}
console.log(ONE.OK)
应用
1. 类型键入
type User = {
outer:string;
innerList:{
innerName:string
}[]
}
type userOut = User['outer'];
type userList = User['innerList'];
type userListItem = userList[number];
let item:userListItem = {
innerName:'yiye'
}
console.log(item)
2 装饰器
function fun() {
return function(target: any, key: string, descriptor: PropertyDescriptor) {
console.log(target);
console.log(key);
console.log(descriptor);
};
}
class A {
@fun()
getDecorator() {
console.log('测试');
}
}
let obj:A = new A();
obj.getDecorator();
3. typeof
-
typeof 关键字在 JS 中用来获取变量的类型,运算结果是一个字符串(值)。而在 TS 中表示的是推算一个变量的类型
let str_1 = 'hello'
console.log(typeof str_1);
type type_1 = typeof str_1;
let obj_1:type_1 = 'dd';
console.log(obj_1)
const str_2 = 'abc'
console.log(typeof str_2);
type type_2 = typeof str_2;
let obj_3:type_2 = 'abc';
interface person{
name:string,
age:number
};
let obj:person = {
name:'yiye',
age:11
}
console.log(typeof obj)
type type_obj=typeof obj;
function foo(key:string){
return key;
}
type type_func = typeof foo;
4.keyof
-
keyof关键字用来获取一个对象类型的所有key类型
type type_1 = {
id:number,
name:string
}
let key_1: keyof type_1 = 'id'
console.log(key_1);
function foo<T extends Object, K extends keyof T>(obj:T,key:K){
console.log(obj[key]);
}
interface key{
name:string,
age:number
}
let obj:key = {
name:'yiye',
age:11
}
foo(obj,'name');
foo(obj,'age');