TypeScript基础一

150 阅读8分钟

一、TypeScript简介

  1. TypeScript由微软开发,是基于javaScript的一个扩展语言。
  2. TypeScript包含了JavaScript的所有内容,即:TypeScript是JavaScript的超集,
  3. TypeScript增加了:静态类型检查、接口、泛型等很多现代开发特性,因此更适合大型项目的开发。
  4. TypeScript需要编译为JavaScript,然后交给浏览器或其他JavaScript运行环境执行。

二、TypeScript出现原因

1. js存在以下问题:js不会报错,不利于项目维护

  • 不清不楚的数据类型
  • 有漏洞的逻辑
  • 访问不存在的属性
  • 低级拼写错误

2.ts支持静态类型检查

在代码运行前进行检查,发现代码的错误或不合理之处,减小运行时异常的出现的几率

3.TypeScript的代码结构更加清晰,便于维护

三、TS编译

从html文件引入编译后的js文件

  1. 全局安装ts
npm install -g typescript
  1. 初始化
tsc init  

3.tsc --watch 监听ts文件

  tsc --watch xx.ts

四、TS数据类型

1. js数据类型

  • 基本类型 :string、number、boolean、null、undefined、symbol;
  • 引用/对象类型:String、Number、Boolean、Array、Function、Date、Error、Math、RegExp、Global、Object

2. TS新增类型

2.1 any:任意类型。

any类型可以赋值给任意类型变量,对定义类型变量产生破坏

image.png

2.2 unknown:未知类型

(1) 可以理解为类型安全的any,适用于:不确定数据的具体类型

image.png (2)解决unknown报错方法(typeOf、断言)

image.png

2.3 never:任何值都不是,不能有任何值,几乎用不到

(1) 几乎不用never去直接定义变量,没有意义

image.png (2) never一般是TS主动推断出的

image.png

(3) never可用于限制函数的类型(函数永远也执行不完或者直接抛出异常的情况返回nerver)

image.png

2.4 void:通常用于函数返回值声明【函数不返回任何值/返回值为空,调用者也不应依赖其返回值做任何操作】

image.png 注意:不能接受void定义的函数返回值做操作,即使函数隐式返回undefined image.png

2.5 object(object和Object):实际应用很少,范围太宽

(1) object image.png (2) Object(除了null和undefined 都可以存)

image.png (3) 声明对象类型

1)字面量类型声明(“ ?”为可选属性) image.png 2)索引签名:允许定义对象可以具有任意数据量的属性,这些属性的键和类型是可变的,常用于描述类型不确定的属性,(具有动态属性的对象)

image.png (4) 声明函数类型

image.png

```js
注意:
1.TS 中的=>在函数类型声明时表示函数类型,描述其参数类型和返回类型
2.JS 中的=>是一种定义函数的语法,是具体函数的实现
3.函数类型声明还可以使用接口,自定义类型等方式
```

(4) 声明数组类型
image.png

2.6 tuple元组

元组是一种特殊的数组类型,可以存固定数量的元素,并且每个元素的类型是已知的且可以不同。元组用于精确描述一组数值的类型,?表示可选元素

image.png

2.7 enum枚举(重点)

作用:增加代码可读性,便于后期维护

(1) 数字枚举

数字枚举一种最常见的枚举类型,其成员的值自动递增且数字枚举还具备反向映射的特点,在下面 代码的打印中,不难发现:可以通过值来获取对应的枚举成员名称。

image.png

不给初始值,默认值从0开始自动递增,否则从当前值递增 image.png (2) 字符串枚举

会丢失反向映射特点 image.png (3) 常量枚举 会减少编译后生成的js代码量,提高运行时的性能

  • 使用常量枚举,编译后js文件只生成我们需要的js代码 image.png
  • 不使用常量枚举,编译后会生成一些额外的js代码 image.png

3.两个自定义类型方式

3.1 type(重点)

type可以为任意类型创建别名,让代码更简洁,可读性更强,同时能更方便的进行类型复用和扩展

(1) 基础用法

image.png

(2) 联合类型(或类型 “ | ”)

联合类型是一种高级类型,值可以是类型中的一种 image.png

(3)交叉类型(且类型 “ & ”)

允许多个类型合并为一个类型,合并后会拥有类型所有成员,常用于对象类型 image.png (4)特殊情况

在函数定义时,限制函数返回值为void,那么函数得返回值必须是空

image.png

使用类型声明限制函数返回值为void时,ts并不会严格要求函数返回空

image.png 原因:是为了确保如下代码成立,我们知道Array,prototype.push的返回一个数字,而Array.prototy pe,forEach方法期望其回调的返回类型是void image.png

3.2 interface(重点)

interface是一种定义结构的方式,主要作用是为:类、对象、函数等规定一种契约,这样可以确保 代码的一致性和类型安全,但要注意interface只能定义格式不能包含任何实现

(1) 定义类结构

使用implements(实现)关键字

interface PersonInterface {
  name: string;
  age: number;
  speak: (n: number) => void;
}

class Person implements PersonInterface {
  constructor(public name: string, public age: number) {}
  speak(n: number) {
    for (let i = 0; i < n; i++)
      console.log(`输出${i}次,我叫${this.name},今年${this.age}岁`);
  }
}

const p = new Person("张三", 18);
p.speak(3);

输出显示

image.png

一个类可以实现多个接口

interface FlyInterface {
  fly(): void;
}
interface SwimInterface {
  swim(): void;
}

class Duck implements FlyInterface, SwimInterface {
  fly() {
    console.log("鸭子可以飞");
  }
  swim() {
    console.log("鸭子可以游泳");
  }
}
(2) 定义对象结构

接口当作对象的类型使用

interface UserInterface {
  name: string;
  age?: number; //可选
  readonly gender: "男" | "女"; //只读
  run: (n: number) => void;
}

const user: UserInterface = {
  name: "张三",
  age: 18,
  gender: "男",
  run: (n) => {
    console.log(`我跑了${n}米`);
  },
};
user.name = "李四";
user.run(4);
// user.gender = "other"; //报错:无法为“gender”赋值,因为它是只读属性。
(3) 定义函数结构
interface CountInterface {
  (a: number, b: number): number;
}

const count: CountInterface = (a, b) => {
  return a + b;
};

(4) 接口之间的继承
interface PersonInterface {
  name: string;
  age: number;
}

interface StudentInterface extends PersonInterface {
  grade: string;
}

const student: StudentInterface = {
  name: "张三",
  age: 18,
  grade: "高一",
};

(5) 接口自动合并(接口可重复定义)
interface PersonInterface {
  name: string;
  age: number;
}
interface PersonInterface {
  gender: string;
}

const person: PersonInterface = {
  name: "张三",
  age: 18,
  gender: "男",
};

总结:何时使用接口?

  • 定义对象的格式:描述数据模型、AP1响应格式、配置对象等等,是开发中用的最多的场景。
  • 类的契约:规定一个类需要实现哪些属性和方法。
  • 自动合并:一般用于扩展第三方库的类型,这种特性在大型项目中可能会用到。
(6) interface和type的区别
  • 相同:interface和type 都可以用于定义对象结构,两者在许多场景是可以互换的。

  • 不同:

    interface:更专注于定义对象和类的结构,支持继承合并

    type:可以定义类型别名,联合类型,交叉类型,但不支持继承和合并。

(7) interface和抽象类的区别
  • 相同:都用于定义一个类的格式

  • 不同:

    接口:只能描述结构,不能有任何实现代码,一个类可以实现多个接口。

    抽象类:既可以包含抽象方法,也可以包含具体方法,一个类只能继承一个抽象类

4. 泛型

泛型允许我们在定义函数、类或接口时,使用类型参数来表示未指定的类型,这些参数在具体使用时才被指定具体的类型。泛型能让同一段代码适用于多种类型,同时仍然保持类型的安全性

(1) 泛型函数

//泛型可以使用任意参数,但约定用大写字母
function logData<T>(data: T) {
  console.log(data);
}
logData<number>(100);
logData<string>("hello");

(2) 泛型可以有多个

function logData<T, U>(data1: T, data2: U): T | U {
  return Date.now() % 2 == 0 ? data1 : data2;
}

console.log(logData<number, string>(101, "hello"));

(3) 泛型接口

interface Person<T> {
  name: string;
  age: number;
  extra: T;
}

type Company = {
  address: string;
  salary: number;
};

const user1: Person<number> = {
  name: "张三",
  age: 18,
  extra: 100,
};
const user2: Person<string> = {
  name: "李四",
  age: 18,
  extra: "附加信息",
};
const user3: Person<Company> = {
  name: "王五",
  age: 30,
  extra: {
    address: "北京市",
    salary: 20000,
  },
};

(4) 泛型类

class Person<T> {
  constructor(public name: string, public age: number, public extraInfo: T) {}
  introduce() {
    console.log(this.name, this.age, this.extraInfo);
  }
}
type Company = {
  address: string;
  salary: number;
};

const p1 = new Person<string>("张三", 18, "附加信息");
p1.introduce();

const p2 = new Person<Company>("张三", 18, {
  address: "北京市",
  salary: 200000,
});
p2.introduce();

输出显示

image.png

五、类型声明文件

类型声明文件是TypeScript中的一种特殊文件,通常以.d.ts作为扩展名。它的主要作用是为现有的JavaScript代码提供类型信息,使得TypeScript能够在使用这些JavaScript库或模块时进行类型检查和提示。

六、常见的TS工具类(重点)

1. Omit (省略/剔除)

从传入的类型中剔除自己不需要的部分形成新的定义类型

image.png

2. pick (挑选)

从传入的类型中挑选自己需要的部分形成新的定义类型

image.png

3. Partial (可选)

将传入的类型全部(必选项&可选项)变为可选

image.png

4.Required (必选的)

将传入的类型全部(必选项&可选项)变为必选项,与Partial相反

image.png

5.ReadOnly (只读)

将传入的类型全部(必选项&可选项)变为只读项,

image.png

6. Exclude

处理联合类型,剔除A中包含B的部分(A - A∩B)

image.png

7. Extract

处理联合类型,从A中选出A,B共同部分(A∩B)

image.png

8. Record

Record<K,T>用于定义一个对象类型,其中键的类型为 K,值的类型为 T

image.png