这是我参与「第四届青训营 」笔记创作活动的第13天
1. 为什么选择typescript
- JS
- 动态类型
- 弱类型语言
- TS
- 静态类型
- 可读性增强:基于语法解析TSDoc,ide增强
- 可维护性增强:在编译阶段暴露大部分错误
- 弱类型语言(类型转换)
- JS的超集
- 包含于兼容所有js特性
- 支持渐进式引入升级
- 静态类型
2. 基本语法
- 基础数据类型
//字符串 const q: string = 'string'; //数字 const w: number = 1; //bool const e: boolean = true; //null const r: null = null; //undefind const t: undefind = undefind - 对象数据类型
const bytedancer: IBtedancer = { job:0000, name:'lihua' } interface IBtedancer { //只读属性,可以在对象初始话外赋值 readonly jobID:number; name:string; sex:'man'|'woman'|'other'; age:number; //可选属性,可以不存在 hooby?:string; //任意属性 [key:string]:any; } - 函数
function add(x:number,y:number):number { return a+b; } const mult: (x:number,y:number) =>number=(x,y)=> x*y; //定义一个接口 interface IMult{ (x:number,y:number):number; } const mult: IMult=(x,y)=>x*y; //对getData函数进行重载 function getDate(type:'string',timestamp?:string):string; function getDate(type:'date',timestamp?:string):Date; function getDate(type:'string'|'date',timestamp?:string): Date|string{ const date = new Date(timestamp); return type ==='string' ? date.toLocaleString() : date; } const x = getDate('date');// Date const y = getDate('string','2018-01-01')//string - 数组类型
type IArr1 = number[] //泛型 type IArr2 = Array<string |number|Record<string,number>>; //元组 type IArr3 = {number,number,string,string}; //接口类型 interface IArr4 { [key:number]:any; } - 类型别名&类型断言
//通过type关键字定义了IObjArr的别名属性
type IObjArr =Array<{
key:string;
[objKey:string]:any;
}>
function keyBy<T extends IObjArr>(objArr: Array<T>){
//未指定类型时,result类型为{}
const result = objArr。reduced((res,val,key)=>{
res[key]=val;
return res;
},{});
//通过as关键字,断言result类型为正确类型
return restult as Record<string,T>;
}
3. 高级类型
- 联合/交叉类型
- 联合类型 A| B ;联合类型表示一个值可以使集中类型之一
- 交叉类型:A&B;多种类型叠加到一起成为一种类型
type IBookList = Array<{ author:string; }&({ type:'history'; range:string; }|{ type:'story'; range:string; })> - 类型保护与类型守护
interface IA {a:1,a1:2} interface IB {b:1,b1:2} function log(arg:IA|IB){ //报错:类型IA|IB上不存在属性a,类型IB上不存在属性a //结论:访问联合类型时,处于程序安全,仅能访问联合类型中的交集部分 if(arg.a){ console.log(arg.a1) }else{ console.log(arg.b1) } } //类型守护 function getIsIA(arg:IA|IB):arg is IA{ return !!(arg as IA).a; } function log2(arg:IA|IB){ if(getIsIA(arg)){ console.log(arg.a1) }else{ console.log(arg.b1) } } - 高级类型
interface IMerge { <T extends Record<string,any>>(sourceObj: Partial<T>,targetObj:T):T; } type IPartial<T extends Record<string,any>> = { [P in keyof T]? : T[P]; } //索引类型:关键字keyof,起相当于取值对象中的所有key组成的字符串字面量如 type IKeys = keyof {a:string;b:number};//=>type IKeys = 'a'|'b' //关键字in,其相当于取值字符串字面量中的一种可能,配合泛型P,即表示每个key //关键字?,痛殴设定对象可选选项即可自动推导图子集类型 - 函数返回值类型
type IDelayCall = <T extends () => any > (func: T) => ReturnType<T>; type IReturnType<T extends (...arg:any) =>any> = T extends (...arg;any)=>infer R ? R:any //关键字extends跟随泛型出现时,表示类型推断,其表达可类比三元表达式,T === 判断类型?A:B //关键字infer出现在类型推中,表示定义类型变量可以用于只带类型 //如该场景下,将函数的返回值类型作为变量,使用新泛型R表示,使用在类型推荐中的结果中
总结
第一次学习typescript的我被完爆了,好难,什么什么泛型,什么什么可以转换,什么什么语法格式,我死了,慢慢学吧,哭。Try to be better