TypeScript入门 | 青训营笔记

63 阅读4分钟

TypeScript入门 | 青训营笔记

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

1.介绍

1.1发展历史

  • 2012-10:微软发布了TypeScript第一个版本(0.8)
  • 2014-10:Angular 发布了基于TypeScript的2.0版本
  • 2015-04:微软发布了Visual Studio Code
  • 2016-05:@ ty pes/react发布,TypeScript 可开发React
  • 2020-09:Vue 发布了3.0 版本,官方支持TypeScript
  • 2021-11:v4.5版本发布

1.2为什么是TypeScript

TypeScript则为静态类型:

  • 可读性增强:基于语法解析TSDoc,ide增强
  • 可维护性增强:在编译阶段暴露大部分错误
  • 多人合作的大型项目中,可以获得更好的稳定性和开发效率

TypeScript是JS的超集:

  • 包含于兼容所有Js特性, 支持共存
  • 支持渐进式引入与升级

2.基本语法

2.1基本数据类型

变量格式一:

 let 变量名:变量类型 = 初始化值;

变量格式二:

 let 变量名:变量类型 | undefined;
 变量名= 变量值

2.1.1数字类型

  • 除了支持十进制和十六进制字面量,TypeScript还支持ECMAScript 2015中引入的二进制和八进制字面量。
 let decLiteral: number = 6;
 let hexLiteral: number = 0xf00d;
 let binaryLiteral: number = 0b1010;
 let octalLiteral: number = 0o744;

2.1.2 布尔类型

  • 布尔值 boolean true/false值
 let isDone: boolean = false;

2.1.3 字符串类型

  • string 单引号(推荐)或双引号或``都可以
 let name: string = "bob";
 name = "smith";

2.1.4 数组类型

  • 数组; 开发中, 数组中的元素为同一类型
  • 语法1:类型[]
 // 表示数值数组
 let list: number[];
 let list: Array<number>;
 ​
 let list: number[] = [1, 2, 3];
  • 语法2:使用泛型写法,Array<元素类型>
 // 表示字符串数组
 let list: string[];
 let list: Array<string>    
 ​
 let list: Array<number> = ['a', 'b', 'c'];
 12345

扩展: 申明二维数组 let arr:number = [ [1,2,3],[7,8,9] ]

2.2对象类型

 const bytedancer: IBytedancer = {
     jobId: 9303245,
     name: 'Lin',
     sex: 'man',
     age: 28,
     hobby: 'swimming',
 }
 ​
 interface IBytedancer {
     /* 只读属性:约束属性不可在对象初始化外赋值 */
     readonly jobId: number;
     name: string;
     sex: 'man' | 'woman' | 'other';
     age: number;
     /* 可选属性:定义该属性可以不存在 */
     hobby?: string;
     /* 任意属性:约束所有对象属性都必须是该属性的子类型 */
     [key: string]: any; // any 任何类型
 }
 ​
 /* 报错:无法分配到"jobId",因为它是只读属性 */
 bytedancer. jobId = 12345;
 /* 成功:任意属性标注下可以添加任意属性 */
 bytedancer .plateform = 'data';
 /* 报错:缺少属性"name", 而hobby可缺省 */
 const bytedancer2: IBytedancer = {
     jobId: 89757,
     sex: " woman ',
     age: 18,
 }

2.3函数类型

两种写法(javascript与typescript)

 function add(x, y!) {
     return x + y;
 }
 const mult = (x, y) =>  x * y;
 function add(x: number, y: number): number {
     return x + y;
 }
 const mult: (x: number, y: number) => number = (x, y) => x * y;
 ​
 ​
 // 简化写法,定义接口IMult
 interface IMult {
     (x: number, y: number): number ;
 }
 const mult: IMult = (x, y) => x * y;

2.4函数重载

 /* 对getDate函数进行重载,timestamp为可缺省参数 */
 function getDate(type: 'string', timestamp?: string): string;
 interface IGetDate {
     (type : 'string', timestamp ?: string): string; 
     (type : 'date', timestamp?: string): Date;
     (type: 'string' | 'date', timestamp?: string): Date | string;
 }
 /* 报错:不能将类型"(type: any, timestamp: any) => string | Date"分配给类型"IGetDate"。
     不能将类型"string | Date" 分配给类型"string"。
     不能将类型 "Date"分配给类型"string"。ts(2322) */
 const getDate2: IGetDate = (type, timestamp) => {
     const date = new Date( timestamp) ; 
     return type === 'string' ? date.toLocaleString() : date;
 }

2.5数组类型

 /* 「类型+方括号」表示 */
 type IArr1 = number[];
 /* 泛型表示 这两种最常用*/ 
 type IArr2 = Array<string | number| Record<string, number> > ;
 /* 元组表示 */
 type IArr3 = [number, number, string, string];
 /* 接口表示 */
 interface IArr4 {
     [key: number]: any;
 }
 ​
 const arrl: IArr1 = [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, {}, []];

2.6TypeScript补充类型

 /* 空类型,表示无赋值 */
 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>;

2.7Typescript泛型

 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);
 /* 报错:类型"number"的参数不能赋给类型“string"的参数 */
 getStrArr(123) ;
 ​
 /* 泛型参数默认类型 */
 type IGetRepeatArr<T = number> = (target: T) => T[];// 与结构中的默认赋值有点类似
 const getRepeatArr: IGetRepeatArr = target => new Array(100).fill(target);// 这里的IGetRepeatArr就是一个类型别名,此处没有传参数给这个类型别名
 /* 报错:类型"string"的参数不能赋给类型“numbe r"的参数 */
 getRepeatArr('123');

2.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> ; 
 }

2.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;