深入浅出typescript‖青训营笔记

56 阅读9分钟

一、为什么要学习ts ts vs js TypeScript 是 JavaScript 的超集,它包含了 JavaScript 的所有元素,可以载入 JavaScript 代码运行,并扩展了 JavaScript 的语法。TypeScript 增加了静态类型、类、模块、接口和类型注解等特性。TypeScript 代码需要通过编译器编译为 JavaScript,然后再交由 JavaScript 解析器执行。

ts带来了什么?

ts课程推荐 awesome-typescript www.typescriptlang.org/play 二、ts基础 ts数据类型

number 类型用于表示数字,可以是整数或浮点数。例如:let num: number = 123; string 类型用于表示字符串,可以使用单引号或双引号来定义。例如:let str: string = 'hello'; boolean 类型用于表示布尔值,只有两个值:true 和 false。例如:let isTrue: boolean = true; null 和 undefined 分别表示空值和未定义。它们的类型分别为 null 和 undefined。例如:let n: null = null; let u: undefined = undefined; symbol 类型表示独一无二的值。例如:let sym1 = Symbol(); let sym2 = Symbol('key'); 数组 类型用于表示一组相同类型的值。可以使用 类型[] 或 Array<类型> 来定义。例如:let arr1: number[] = [1, 2, 3]; let arr2: Array = [1, 2, 3]; 对象 类型用于表示一个对象,可以使用接口或类型别名来定义对象的类型。例如:

css复制代码interface Person { name: string; age: number; } let person: Person = { name: 'lisa', age: 25 };

枚举(Enum) 类型用于定义一组命名的常数。当一个变量有几种可能的取值时,可以将它定义为枚举类型。例如,我们可以定义一个枚举类型来表示颜色:

typescript复制代码enum Color { Red, Green, Blue } let c: Color = Color.Green;

在上面的例子中,我们定义了一个名为 Color 的枚举类型,它包含三个成员,分别表示红、绿、蓝三种颜色。然后我们定义了一个名为 c 的变量,它的类型为 Color,并将它的值设置为 Color.Green。 枚举成员默认从 0 开始递增,也可以手动指定成员的值: typescript复制代码enum Color { Red = 1, Green, Blue } let c: Color = Color.Green;

在上面的例子中,我们将 Red 的值指定为 1,那么后面的成员会依次递增,即 Green 的值为 2,Blue 的值为 3。 还可以通过枚举值来获取它的名字: typescript复制代码enum Color { Red = 1, Green, Blue } let colorName: string = Color[2]; console.log(colorName); // 输出 'Green'

在上面的例子中,我们使用 Color[2] 来获取枚举值为 2 的成员的名字,即 'Green'。

never 类型表示永不存在的值的类型,常用于抛出异常或无限循环的函数返回值类型。例如:

typescript复制代码function error(message: string): never { throw new Error(message); }

any 类型表示任意类型,可以赋予任意类型的值。例如:let notSure: any = 6; notSure = 'I am string'; notSure = false; unknown 类型与 any 类型类似,但更安全,因为在对 unknown 类型的值进行操作之前,需要先进行类型判断。例如:

ini复制代码let value: unknown; value = true; value = 42; value = 'hello'; if (typeof value === 'string') { console.log(value.toUpperCase()); }

void 类型表示没有任何返回值的函数返回值类型。例如:

javascript复制代码function warnUser(): void { console.log('This is a warning message'); }

元组(Tuple)类型用来表示一个已知元素数量和类型的数组,各元素的类型不必相同。例如,你可以定义一个元组,它包含一个 string 类型元素和一个 number 类型元素: typescript复制代码let tuple: [string, number]; tuple = ['hello', 123]; // OK tuple = [123, 'hello']; // Error

在上面的例子中,我们定义了一个名为 tuple 的元组类型变量,它包含两个元素,第一个元素的类型为 string,第二个元素的类型为 number。当我们给 tuple 赋值时,需要提供两个元素,并且元素的类型需要与定义时指定的类型一致。 我们可以像访问数组中的元素一样访问元组中的元素,例如: typescript复制代码let tuple: [string, number] = ['hello', 123]; console.log(tuple[0]); // 输出 'hello' console.log(tuple[1]); // 输出 123

课程中enum的举例子图片

课程中never的举例子图片

ts函数类型 在 TypeScript 中,函数类型用于定义函数的参数类型和返回值类型。 定义函数的规则如下图:

这里解释下老师课上说的函数重载: 函数重载是指根据参数的类型执行不同的函数。多数用于传入不同的参数得到不同的结果。重载分为两个部分(缺一不可):声明和实现。 举个例子,假设我们有一个函数,可以接收string类型相拼接,也可以接收number类型相加。 有一个函数叫做double,它可以接收number类型并返回它的两倍,也可以接收string类型并返回它与自身拼接的结果。代码如下: typescript复制代码function double(x: number): number; function double(x: string): string; function double(x: number | string): number | string { if (typeof x === 'number') { return x * 2; } else { return x + ', ' + x; } } let d = double(1);

ts—interface 1、定义: 为了定义对象类型。例如 ts复制代码interface Person { name: String, age: Number } let tom: Person = { name: 'Tom', age: 25 };

2、特点:

可选属性:接口里的属性不全都是必需的。带有可选属性的接口与普通的接口定义差不多,只是在可选属性名字定义的后面加一个?符号。 可读属性:readonly 可以描述自定义属性 可以描述函数类型:

js复制代码interface AddFunc { (num1: number, num2: number): number; }

总结:接口非常灵活。

ts_类 1、写法:与js差不多,增加了一些定义。 2、特点:

增加了private, public, protected修饰符 抽象类:1、只能被继承,不能被实例化。2、作为基类,抽象方法必须被子类实现。 interface约束类,使用implements关键字

三、ts进阶 高级类型 1、联合类型与交叉类型

联合类型:联合类型通过 | 符号连接多个类型从而生成新的类型。它主要是取多个类型的交集,即多个类型共有的类型才是联合类型最终的类型。联合类型可以是多个类型其中一个,可做选择。

交叉类型:交叉类型由一组有序的成员类型构成,交叉类型表示类型同时为多个类型,等同于运算符 &&,类似于数学运算中的乘法。交叉类型也是通过交叉类型字面量来定义的。

2、类型断言 类型断言的主要作用是在你比 TypeScript 更清楚某个值的类型的情况下,手动指定一个值的类型。这样可以避免 TypeScript 编译器报错,同时也可以让你更好地利用 TypeScript 的类型系统。 类型断言是 TypeScript 中的一个概念,它允许你手动指定一个值的类型。类型断言有两种形式。一种是“尖括号”语法: typescript复制代码let someValue: any = "this is a string"; let strLength: number = (someValue).length;

另一种是 as 语法: typescript复制代码let someValue: any = "this is a string"; let strLength: number = (someValue as string).length;

两种形式是等价的。需要注意的是,在使用 JSX 时,只有 as 语法断言是被允许的。 3、类型别名(type vs interface) 二者都是给类型起别名。 相同点:都可以定义对象或函数,都允许继承 不同点:

interface是用来定义对象,type用来定义别名方便使用。 type可以定义基本类型,interface不行。 interface可以合并重复声明,type不行

总结:interface是一个接口的概念,用来描述对象。type别名的概念,用来对各个别名定义。

ts—泛型-什么时候需要泛型? 1、泛型是 TypeScript 中的一个重要概念,它允许你在定义函数、接口、类时不预先指定具体的类型,而是在使用时指定类型。泛型可以用来创建可重用的组件,一个组件可以支持多种类型的数据。这样用户就可以以自己的数据类型来使用组件。 2、泛型的语法是使用尖括号 <> 来包裹类型变量,一般可以用 T 来表示或者其他任何表示。T 相当于一个占位符或者变量,在使用时把定义的类型像参数传入。泛型可以在定义函数、接口或类时不预先指定类型,而是使用时指定类型。 3、使用时有两种方法指定类型: 当使用泛型时,有两种方法可以指定类型:

显式指定类型:在调用泛型函数或实例化泛型类时,可以在尖括号 <> 中显式指定类型。例如:

typescript复制代码function identity(arg: T): T { return arg }

let output = identity("myString");

类型推断:在调用泛型函数或实例化泛型类时,如果不显式指定类型,TypeScript 编译器会根据传入的参数自动推断出类型。例如:

typescript复制代码function identity(arg: T): T { return arg } let output = identity("myString");

在这个例子中,虽然我们没有显式指定类型,但 TypeScript 编译器会根据传入的参数 "myString" 推断出 T 的类型为 string。 4、泛型的作用:临时占位,通过传过来的类型进行临时推导。 如何使用泛型来定义一个函数: typescript复制代码function identity(arg: T): T { return arg; }

在这个例子中,我们定义了一个名为 identity 的函数,它接收一个类型为 T 的参数 arg 并返回一个类型为 T 的值。当我们调用这个函数时,可以指定 T 的具体类型: typescript复制代码let output = identity("myString");

ts—泛型-基础操作符 在 TypeScript 中,有一些基础操作符可以用来操作泛型类型:

typeof:typeof 操作符可以用来获取一个变量的类型。例如:

typescript复制代码let s = "hello"; type TypeOfS = typeof s; // TypeOfS 的类型为 string

keyof:keyof 操作符可以用来获取一个对象类型的所有键。例如:

typescript复制代码interface Person { name: string; age: number; }

type PersonKeys = keyof Person; // PersonKeys 的类型为 "name" | "age"

in:in 操作符可以用来遍历枚举类型。例如:

typescript复制代码type Keys = "a" | "b" | "c"; type Obj = { [p in Keys]: any }; // Obj 的类型为 { a: any, b: any, c: any }

T[K]:索引访问操作符 T[K] 可以用来获取对象类型 T 的属性 K 的类型。例如:

typescript复制代码interface Person { name: string; age: number; }

type NameType = Person["name"]; // NameType 的类型为 string

extends:条件类型中的 extends 关键字可以用来判断一个类型是否能够赋值给另一个类型。例如:

typescript复制代码interface Animal { name: string; }

interface Cat extends Animal { meow(): void; }

type IsCat = T extends Cat ? true : false;

type A = IsCat; // A 的类型为 true type B = IsCat; // B 的类型为 false

ts—泛型-常用工具类型

四、ts实战 声明文件 在 TypeScript 中,当我们使用第三方库时,通常需要提供一个声明文件来描述这个库的类型信息。声明文件通常以 .d.ts 为后缀,它包含了第三方库的类型定义。

declare:declare 关键字用来定义一个全局变量。例如:

typescript复制代码declare var $: any;

.d.ts:声明文件通常以 .d.ts 为后缀,它包含了第三方库的类型定义。例如:

typescript复制代码// jquery.d.ts declare var $: any;

@types:@types 是一个 npm 包,它包含了许多第三方库的声明文件。你可以通过安装对应的 @types 包来获取第三方库的类型定义。例如:

bash复制代码npm install @types/jquery

tsconfig.json:在 tsconfig.json 文件中,你可以配置 TypeScript 编译器的相关选项,包括声明文件的相关配置。例如:

json复制代码{ "compilerOptions": { "typeRoots": ["./node_modules/@types"] } }

泛型约束后端接口类型

作者:胡萝卜会飞 链接:juejin.cn/post/722600…