TypeScript敲门 (二)| 青训营笔记

61 阅读4分钟

这是我参与「第四届青训营 」笔记创作活动的第12天

高级类型

联合/交叉类型

联合类型:IA|IB;联合类型表示一个值可以是几种类型之一

交叉类型: IA & IB;多种类型叠加到一起成为一种类型,它包含了所需的所有类型的特性

 const bookList = [{ author: 'xiaoming',
 type: 'history',
 range: '2001-2021}
,{
   author: 'xiaoli',
   type: 'story'
   theme: 'love',
}]
 type IBookList = Array<{
   author: string;
 })&{
   type: 'history';
  range: string;
 }|{
   type: 'story';
 theme: string;
 }>
​

类型保护与类型守卫

 interface IA {a: 1, al: 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);
 } 
 }
​

类型改造

类型守卫只有当两个类型完全没有重合点的时候 需要写一个类型守卫

 interface IA {a: 1, al: 2}
 interface IB {b: 1, b1: 2}
 //声明一个类型守卫
/*类型守卫:定义一个函数,它的返回值是一个类型谓词,生效范围为子作用域*/
 function getIsIA(arg: IA | IB): arg is IA {
 //as的类型断言
 //当他存在a的时候,断言她一定是个IA类型
   return !!(arg as IA).a;
 }
​
 function log2(arg: IA | IB){
   if (getIsIA(arg)) {
     console. log(arg.a1)
   }else{
   
 console. log(arg.b1);
   }
 }
​
//实现函数reverse
//其可将数组或字符串进行反转
 function reverse(target: string | Array<any>){
   /* typof类型保护
 if (typeof target === 'string') {
 return target.split(''). reverse().join('')
 }
 * instance类型保护*/
 //进行数组判别
 if (target instanceof Object) {
   return target. reverse();
 }
}
 //实现函数logBook类型
//函数接受书本类型,并logger出相关特征 
function logBook(book: IBookItem) {
  //联合类型+类型保护=自动类型推断
  if (book. type === 'history') 
  { 
    console. log (book. range)
  } else{
     console. log (book. theme);
  }
}

高级类型

sourobj和targetobj做合并

//实现merge函数类型
//要求sourceObj必须为targetObj的子集
 function mergel(sourceObj, targetobj) {
  const result = {...source0bj }; 
  for(let key in targetobj) {
    const itemVal = sourceObj [key];
    itemVal && ( result [key] = itemVal );
  }
  return result;
}
 function merge2(source0bj, targetobj) {
  return {...source0bj, ...target0bj}
}

不知道传入的人不知道传入的是什么object

 interface ISourceObj{
  x?: string;
  y?: string;
 }
 interface ITargetobj {
   x: string;
   y:string
 }
​
 type IMerge = (sourceObj: ISourceobj, target0bj: ITarget0bj)
 =>ITargetobj;
 /**
*类型实现繁琐:若obj类型较为复杂,则声明source和target便需要大量重复2遍
*容易出错:若target增加/减少key,则需要source联动去除
//xy或者any都没办法严格限定
*/

通过使用泛型 定义的时候不明确 使用的时候明确

 interface IMerge {
 //Record<string, any>> 简单的any的表达
  <T extends Record<string, any>>(sourceObj: Partial<T>, target0bj: 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
//关键字【?】 ,通过设定对象可选选项,即可自动推导出子集类型

高级类型通过基础语法表达,partical是内置类型,直接使用就可以

函数返回值类型

 //实现函数delayCall的类型声明
//delayCall接受一个函数作为入参,其实现延迟1s运行函数
//其返回promise,结果为入参函数的返回结果
 function delayCall(func) {
   return new Promise (resolve => {
     setTimeout(() =>{
     const result = func();
     resolve(result);
     }, 1000);
  });
 }
​
//类型声明 :入参 出参
//通过泛型
//泛型限定,定义了一个函数 返回范围最大的函数
 type IDelayCall = <T extends () => any>(func: T) => ReturnType<T>;
 //定义时不明确 使用泛型
 //function设置了更大的限定 出入参都可以是最大范围 符合函数标准就行
 //?:三元表达式 
 //extends这里是个声明 类型推断 语法类似三元表达式 类型匹配 作用等于三等号
 type IReturnType<T extends (...args: any) => any> = T extends (...args: any) => infer R ? R: any
//关键字【extends】跟随泛型出现时,表示类型推断,其表达可类比三元表达式
//如T-判断类型?类型A:类型B
//关键字【infer】出现在类型推荐中,表示定义类型变量,可以用于指代类型
//如该场景下,将函数的返回值类型作为变量,使用新泛型R表示,使用在类型推荐命中的结果中

工程应用

浏览器WEB

TypescriptI程应用 - Web

1、 配置webapack loader相关配置

webpack不能识别的文件转化为可以识别的文件,ts转js

2、 配置tsconfig.js文件

这个文件官网有配置项

3、运行webpack启动/打包

4、 loader处理ts文件时,会进行编译与类型检查

NODEJS

01.使用TSC编译

  1. 安装Node5npm
  1. 配置tsconfig.js文件
  1. 使用npm安装tsc
  1. 使用tsc运行编译得到js文件