一、为什么要学习ts
ts vs js
TypeScript 是 JavaScript 的超集,它包含了 JavaScript 的所有元素,可以载入 JavaScript 代码运行,并扩展了 JavaScript 的语法。TypeScript 增加了静态类型、类、模块、接口和类型注解等特性。TypeScript 代码需要通过编译器编译为 JavaScript,然后再交由 JavaScript 解析器执行。
ts带来了什么?
ts课程推荐
二、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<number> = [1, 2, 3];
- 对象 类型用于表示一个对象,可以使用接口或类型别名来定义对象的类型。例如:
interface Person {
    name: string;
    age: number;
}
let person: Person = {
    name: 'lisa',
    age: 25
};
- 枚举(Enum) 类型用于定义一组命名的常数。当一个变量有几种可能的取值时,可以将它定义为枚举类型。例如,我们可以定义一个枚举类型来表示颜色:
enum Color {
    Red,
    Green,
    Blue
}
let c: Color = Color.Green;
在上面的例子中,我们定义了一个名为 Color 的枚举类型,它包含三个成员,分别表示红、绿、蓝三种颜色。然后我们定义了一个名为 c 的变量,它的类型为 Color,并将它的值设置为 Color.Green。
枚举成员默认从 0 开始递增,也可以手动指定成员的值:
enum Color {
    Red = 1,
    Green,
    Blue
}
let c: Color = Color.Green;
在上面的例子中,我们将 Red 的值指定为 1,那么后面的成员会依次递增,即 Green 的值为 2,Blue 的值为 3。
还可以通过枚举值来获取它的名字:
enum Color {
    Red = 1,
    Green,
    Blue
}
let colorName: string = Color[2];
console.log(colorName); // 输出 'Green'
在上面的例子中,我们使用 Color[2] 来获取枚举值为 2 的成员的名字,即 'Green'。
- never 类型表示永不存在的值的类型,常用于抛出异常或无限循环的函数返回值类型。例如:
function error(message: string): never {
    throw new Error(message);
}
- any 类型表示任意类型,可以赋予任意类型的值。例如:let notSure: any = 6; notSure = 'I am string'; notSure = false;
- unknown 类型与 any 类型类似,但更安全,因为在对 unknown 类型的值进行操作之前,需要先进行类型判断。例如:
let value: unknown;
value = true;
value = 42;
value = 'hello';
if (typeof value === 'string') {
    console.log(value.toUpperCase());
}
- void 类型表示没有任何返回值的函数返回值类型。例如:
function warnUser(): void {
    console.log('This is a warning message');
}
元组(Tuple)类型用来表示一个已知元素数量和类型的数组,各元素的类型不必相同。例如,你可以定义一个元组,它包含一个 string 类型元素和一个 number 类型元素:
let tuple: [string, number];
tuple = ['hello', 123]; // OK
tuple = [123, 'hello']; // Error
在上面的例子中,我们定义了一个名为 tuple 的元组类型变量,它包含两个元素,第一个元素的类型为 string,第二个元素的类型为 number。当我们给 tuple 赋值时,需要提供两个元素,并且元素的类型需要与定义时指定的类型一致。
我们可以像访问数组中的元素一样访问元组中的元素,例如:
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类型并返回它与自身拼接的结果。代码如下:
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、定义: 为了定义对象类型。例如
interface Person {
    name: String,
    age: Number
}
let tom: Person = {
  name: 'Tom',
  age: 25
};
2、特点:
- 可选属性:接口里的属性不全都是必需的。带有可选属性的接口与普通的接口定义差不多,只是在可选属性名字定义的后面加一个?符号。
- 可读属性:readonly
- 可以描述自定义属性
- 可以描述函数类型:
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 中的一个概念,它允许你手动指定一个值的类型。类型断言有两种形式。一种是“尖括号”语法:
let someValue: any = "this is a string";
let strLength: number = (<string>someValue).length;
另一种是 as 语法:
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、使用时有两种方法指定类型: 当使用泛型时,有两种方法可以指定类型:
- 显式指定类型:在调用泛型函数或实例化泛型类时,可以在尖括号 <>中显式指定类型。例如:
function identity<T>(arg: T): T {
  return arg
 }
let output = identity<string>("myString");
- 类型推断:在调用泛型函数或实例化泛型类时,如果不显式指定类型,TypeScript 编译器会根据传入的参数自动推断出类型。例如:
function identity<T>(arg: T): T {
  return arg
 }
let output = identity("myString");
在这个例子中,虽然我们没有显式指定类型,但 TypeScript 编译器会根据传入的参数 "myString" 推断出 T 的类型为 string。
4、泛型的作用:临时占位,通过传过来的类型进行临时推导。
如何使用泛型来定义一个函数:
function identity<T>(arg: T): T {
  return arg;
}
在这个例子中,我们定义了一个名为 identity 的函数,它接收一个类型为 T 的参数 arg 并返回一个类型为 T 的值。当我们调用这个函数时,可以指定 T 的具体类型:
let output = identity<string>("myString");
ts—泛型-基础操作符
在 TypeScript 中,有一些基础操作符可以用来操作泛型类型:
- typeof:- typeof操作符可以用来获取一个变量的类型。例如:
let s = "hello";
type TypeOfS = typeof s; // TypeOfS 的类型为 string
- keyof:- keyof操作符可以用来获取一个对象类型的所有键。例如:
interface Person {
  name: string;
  age: number;
}
type PersonKeys = keyof Person; // PersonKeys 的类型为 "name" | "age"
- in:- in操作符可以用来遍历枚举类型。例如:
type Keys = "a" | "b" | "c";
type Obj = { [p in Keys]: any }; // Obj 的类型为 { a: any, b: any, c: any }
- T[K]:索引访问操作符- T[K]可以用来获取对象类型- T的属性- K的类型。例如:
interface Person {
  name: string;
  age: number;
}
type NameType = Person["name"]; // NameType 的类型为 string
- extends:条件类型中的- extends关键字可以用来判断一个类型是否能够赋值给另一个类型。例如:
interface Animal {
  name: string;
}
interface Cat extends Animal {
  meow(): void;
}
type IsCat<T> = T extends Cat ? true : false;
type A = IsCat<Cat>; // A 的类型为 true
type B = IsCat<Animal>; // B 的类型为 false
ts—泛型-常用工具类型
四、ts实战
声明文件
在 TypeScript 中,当我们使用第三方库时,通常需要提供一个声明文件来描述这个库的类型信息。声明文件通常以 .d.ts 为后缀,它包含了第三方库的类型定义。
- declare:- declare关键字用来定义一个全局变量。例如:
declare var $: any;
- .d.ts:声明文件通常以- .d.ts为后缀,它包含了第三方库的类型定义。例如:
// jquery.d.ts
declare var $: any;
- @types:- @types是一个 npm 包,它包含了许多第三方库的声明文件。你可以通过安装对应的- @types包来获取第三方库的类型定义。例如:
npm install @types/jquery
- tsconfig.json:在- tsconfig.json文件中,你可以配置 TypeScript 编译器的相关选项,包括声明文件的相关配置。例如:
{
  "compilerOptions": {
    "typeRoots": ["./node_modules/@types"]
  }
}