Typescript入门| 青训营笔记

64 阅读6分钟

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

Typescript入门:

一:为什么选择Typescript,什么是Typescript

1.      Typescript是静态类型语言(不可以直接执行,要先进行一次编译才可以执行),弱类型语言。

2.      静态类型的优点:

a)       可读性增强:基于语法解析TSDoc,ide增强。

b)       可维护性增强:在编译阶段暴露大部分错误=>多人合作的大型项目中,获得更好的稳定性和开发效率

3.      Js的超集:

a)       包含于兼容所有J特性,支持共存

b)       支持渐进式引入与升级

二:基本语法:

1.      基础数据类型:

/*字符串*/

const q: string = 'string';

/*数字*/

const W: number = 1;

/*布尔值*/

const e: boolean = true ;

/*null*/

const r: null = nult;

/* undefined */

const t: undefined = undef ined ;

2.      对象类型:

interface IBytedancer {

/*只读属性:约束属性不可在对象初始化外赋值*/

readonly jobId: number ;

name: string;

sex: 'man' | 'woman' | ' other' ;

age: number ;

/* 可选属性: 定义该属性可以不存在*/

hobby?: string;

/*任意属性:约束所有对象属性都必须是该属性的子类型*/

[key: string]: any;(任何属性)

}



/*报错:无法分配到"jobId",因为它是只读属性*/

bytedancer. jobId

= 12345;

/*成功:任意属性标注下可以添加任意属性*/

bytedancer .plateform = 'data' ;

/*报错:缺少属性"name" ,

hobby可缺省*/

const bytedancer2: IBytedancer = {

jobId: 89757,

sex:'woman'

age:18,

}

3.      函数类型:

function add(x: number, y: number): number {

return x + y;

}

const mult: (x: number, y: number) => number = (x, y) => X * y;

4.      函数重载:

/*对getDate函数进行重载,t imes tamp为可缺省参数*/

function getDate(type:' string', timestamp?: string): string ;

interface IGetDate {

(type:string ' , t imestamp? :string): string ;

(type: 'date', timestamp?: string): Date;

(type:string' | 'date', timestamp?: string): Date| string ;

/*不能将类型"(type: any, timestamp: any) => string| Date"分配给类型“IGetDate"。

不能将类型“stringI Date" 分配给类型“string"。

不能将类 型"Date"分配给类型"string"。ts(2322) */

const getDate2: IGetDate = (type, timestamp) => {

const date = new Date (t imestamp);

return type === 'string' ? date. toLocaleString() : date;

}

5.      数组类型:

/*「类型+方括号」表示*/

type IArr1 = number[] ;

/*泛型表示*/

type IArr2 = Array<string| number|

Record<string, number>> ;

/*元祖表示*/

type IArr3 = [number, number, string, string] ;

/*接口表示*/

interface IArr4 {

[key: number]: any;

}



const arr1: IArrl = [1, 2, 3, 4, 5, 6];

const arr2:

IArr2=[1,2,'3','4',{a:1}];

const arr3: IArr3 = [1, 2, '3''4'];

const arr4: IArr4 = ['string', () => null, {}, []];

(一般使用前两种数组定义)

6.      Typscript补充类型:

/*空类型,表示无赋值*/

type IEmptyFunction = () => void;

/*任意类型,是所有类型的子类型*/

type IAnyType = any;

/*枚举类型:支持枚举值到枚举名的正、反向映射*/

enum EnumExample {

add =mult

EnumExample['add'] === '+';

EnumExample['+'] === 'add' ;

enum ECorlor { Mon, Tue, Wed, Thu, Fri, Sat, Sun };

ECorlor['Mon'] === 0;

ECorlor[0] === 'Mon' ;

/*泛型*/

type INumArr = Array<number> ;

7.      Typescript泛型:

function getRepeatArr(target) {

return new Array(100). fill(target);

}

type IGetRepeatArr = (target: any) => any[];

/*不预先指定具体的类型,而在使用的时候再指定类型的一种特性*/

type IGetRepeatArrR = <T>(target: T) => T[];



/*泛型接口&多泛型*/

interface IX<T, U> {

key: T ;

val: U;

}

/*泛型类*/

class IMan<T> {

instance: T;

}

/*泛型别名*/

type ITypeArr<T> = Array<T>;

 

/*泛型约束:限制泛型必须符合字符串*/

type IGetRepeatStringArr = <T extends string>(target: T) => T[] ;

const getStrArr: IGetRepeatStringArr = target => new Array(100). fill(target);

/*报错:类型"numbe r”"的参数不能赋给类型"string"的参数*/

getStrArr(123);

/*泛型参数默认类型*/

type IGetRepeatArr<T = number> = (target: T) => T[];

const getRepeatArr: IGetRepeatArr = target => new Array(100) . fill(target) ;

/*报错:类型"string"的参数不能赋给类型“number"的参数*/

getRepeatArr('123');

8.      类型别名&类型断言:

/*通过type关键字定义了IObjArr的别名类型*/

type IObjArr = Array<{

key: string;

[objKey: string]: any;

}>

function keyBy<T extends IObjArr>(objArr: Array<T>) {

/* 未指定类型时, result类型为 {} */

const result = objArr .reduce((res, val, key) => {

res [key] = val;

return res ;

}, {});

/*通过as关键字,断言result类型为正确类型*/

return result as Record<string, T>;

}

9.      字符串/数字 字面量:

/*允许指定字符串/数字必须的固定值*/(或的关系)

/* IDomTag必须为html、body、 div、 span中的其一*/

type IDomTag = 'html' | ' body' | 'div' | 'span' ;

/* IOddNumber必须为1、 3、5、7、9中的其一*/

type IOddNumber= 1| 3| 5| 7| 9

三:高级类型:

1.      联合\交叉类型

a)       联合类型: iA | iB;联合类型表示个值可以是几种类型之一

b)       交叉类型: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;

} )>

2.      类型保护与类型守卫:

interface IA { a: 1, a1: 2 }

interface IB { b: 1, b1: 2 }

/*类型守卫:定义一个函数,它的返回值是一 个类型谓词,生效范围为子作用域*/

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) ;

}

}

另一种:

//实现函数reverse

//实现函数logBook类型

//函数接受书本类型,并logger出相关特征

function logBook (book: IBookItem) {

//联合类型+类型保护=自动类型推断

if (book. type === 'history') {

console. log (book. range )

} else {

console . log (book. theme) ;

3.      高级类型:(基础类型构建出来的)

/**

*实现merge函数类型

*要求sourceObj必须为targetObj的子集

**/

function merge1 (source0bj, targetobj) {

const result = {  ...sourceObj};

for (let key in targetobj) {

const itemVal = source0bj [key] ;

i temVal && ( result[key] = itemVal ) ;

}

return result;

}

function merge2 (source0bj, targetObj) {

return {. . ..source0bj, . . . targetObj } ;

}



interface ISourceObj {

x? : string;

y? : string;

interface ITargetobj {

x : string;

y : string

}

type IMerge = ( sourceobj: ISourceObj, targetobj: ITargetObj )

=> ITargetObj ;

/**

*类型实现繁琐:若obj类型较为复杂,则声明source和target便需要大 量重复2遍

*容易出错:若target增加/减少key,则需要source联动去除

*/



interface IMerge {(泛型定义)

<T extends Record<string, any>> (source0bj: Partial<T>, targetobj: T) : T;

}

type IPartial<T extends Record<string, any>> = {

[PinkeyofT]?:T[P];

}

//索引类型:关键字[keyof] ,其相当于取值对象中的所有key组成的字符串字面量,如

type IKeys = keyof { a: string; b: number};  //=>typeIKeys="a"|"b"

//关键字[in] ,其相当于取值字符串字面量中的一种可能,配合泛型P,即表示每个key

//关键字[?] ,通过设定对象可选选项,即可自动推导出子集类型

4.      函数返回值类型:

//实现函数delayCall的类型声明

// delayCal接受一个函数作为入参, 其实现延迟1s运行函数

//其返回promise,结果为入参函数的返回结果

function delayCall (func) {

return new Promise (resolve => {

se tTimeout ( () => {

const result = func() ;

resolve (result) ;

},1000) ;

}) ;

}

             

type IDelayCall = <T extends () => any> (func: T) => ReturnType<T> ;

type IReturnType<T extends (. . .args: any) => any> = T extends (. . .args: any)

=>inferR?R:any

//关键字[extends] 跟随泛型出现时,表示类型推断,其表达可类比三元表达式

//如T===判断类型?类型A:类型B

//关键字[infer] 出现在类型推荐中,表示定义类型变量,可以用于指代类型

//如该场景下,将函数的返回值类型作为变量,使用新泛型R表示,使用在类型推荐命中的结果中

四:工程应用:

1.      Web:

a)       配置webapack loader相关配置

b)       配置tsconfig.js文件

c)        运行webpack启动,打包

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

2.      Node:

a)       安装Node与npm

b)       配置tsconfig. js文件

c)        使用npm安装tsc使用tsc运行编译得到js文件