typescript初学 | 青训营笔记

119 阅读3分钟

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

暂时度过了军训的忙碌阶段,于是就想着忙里偷闲的学一下ts,毕竟似乎ts越来越受欢迎了(我的千行小应用尚且用js写起来不爽,更何况是大型应用呢)

TypeScript

JavaScriptTypeScript
动态类型静态类型
弱类型弱类型

优势:

  • 可读性增强:IDE解析能力增强
  • 可维护性增强:在编译阶段就会暴露大部分错误
  • 更有利于多人合作

基本语法

JavaScript

 const q = "string";
 const w = 1;
 const e = true;
 const r = null;
 const t = undefined;

TypeScript

 const q: string = "string";
 const w: number = 1;
 const e: boolean = true;
 const r: null = null;
 const t: undefined = undefined;

对象类型

 interface IPerson {
     readonly Id: number;
     //只读属性
     name: string;
     sex: "man" | "woman" | "other";
     age: number;
     hobby?: string;
     [key: string]: any;
 }
 ​
 const person: IPerson = {
     Id: 114514,
     name: "wujinhjun",
     sex: "man",
     age: 20,
     hobby: "sleep"
 }

函数类型

 interface ISearchArgs {
     (x: number, y: number): number
 }
 ​
 const mySum: ISearchArgs = function (x, y) {
     return x + y;
 }
 ​
 //或者是
 ​
 function add (x: number, y: number): number {
     return x + y;
 }

函数重载

 function reverse(x: number): number;
 function reverse(x: string): string;
 function reverse(x: number | string): number | string | void {
     if (typeof x === "number") {
         return Number(x.toString().split('').reverse().join(''));
     } else if (typeof x === "string") {
         return x.split('').reverse().join('');
     }
 }

前两次是函数定义,最后一次是函数实现 值得注意的是ts会从最前面的开始匹配,如果多个函数具有包含关系,需要优先把精确的定义写在前面

数组类型

 type IArr1 = number[];
 type IArr2 = Array<string | number | Record<string, number>>;
 type IArr3 = [number, number, string];
 interface IArr4 {
     [index: number]: any
 }
 ​
 const arr1: IArr1 = [1, 2, 3, 4, 5, 6];
 const arr2: IArr2 = [1, 2, 3, "4", "5", { a: 1 }];
 const arr3: IArr3 = [1, 2, "3"];
 const arr4: IArr4 = ['string', () => null, {}, []];

IArr1:表示只能包含number类型

IArr2:表示可以包含string、number、key为string,value为number的object

IArr3:表示只能是number、number、string类型

IArr4:接口表示法

类型断言

用来手动指定一个值的类型

用途:

将联合类型断言为其中一个类型:当联合类型的具体类型不确定时,只能访问此联合类型中所有类型的方法的交集

但有时又需要一些其他方法,那就可以使用类型断言将类型断言成具体某个。但是,类型断言无法避免运行时错误,只能通过ts编译器,所以需要慎用

any与断言:

任何类型都可以断言成any,any也可以断言成任何具体类型

但需要注意的是不能滥用as any,也不能完全弃之不用

限制:

A兼容B时,AB间可以相互断言

类型别名:

给类型起个新的名字:

 type Name = string;
 type NameResolver = () => string;
 type NameOrResolver = Name | NameResolver;
 function getName(n: NameOrResolver): Name {
     if (typeof n === "string") {
         return n;
     } else {
         return n();
     }
 }

字符串字面量:

之前其实已经有提过了:

 type sex = "man" | "woman" | "other"

只能取这几个字符串中的一个

泛型:

可以不预先指定具体类型,在使用时再指定类型

 function createArray<T>(length: number, value: T): Array<T> {
     let result: T[] = [];
     for (let i = 0; i < length; i++) {
         result[i] = value;
     }
     return result;
 }

多个泛型:

 function swap<T, U>(tuple: [T, U]): [U, T] {
     return [tuple[1], tuple[0]];
 }

泛型约束:

 type IGetStringArr = <T extends string>(target: T) => T[];
 const getStrArr: IGetStringArr = target => new Array(100).fill(target);

联合/交叉类型

联合类型: IA|IB:一个值是几种类型之一

交叉类型: IA&IB:多种类型叠加到一起成为一种类型

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

类型守卫与类型保护:

正在学ing……