Typescript开发重点

以下是TypeScript(TS)的核心重点知识梳理,从基础到进阶,覆盖日常开发的核心场景:

一、TypeScript 基础认知

TypeScript 是 JavaScript 的超集,在 JS 基础上增加了静态类型系统,核心价值是:

  • 类型安全:编译时发现类型错误,减少运行时 Bug。
  • IDE 智能提示:提升开发效率和代码可维护性。
  • 渐进式 adoption:可与 JS 共存,逐步迁移。

二、核心:类型系统

1. 基础类型

类型 说明 示例
string 字符串 let name: string = 'TS'
number 数字(整数/浮点数) let age: number = 25
boolean 布尔值 let isOk: boolean = true
null/undefined 空值/未定义(默认是所有类型的子类型) let n: null = null
symbol/bigint 唯一值/大整数(ES6+) let s: symbol = Symbol()
any 任意类型(慎用,失去类型安全) let val: any = 123
unknown 未知类型(比 any 安全,需类型断言) let val: unknown = 'hi'
void 无返回值(函数常用) function log(): void { }
never 永不存在的值(如抛出错误/死循环) function err(): never { throw new Error() }

重点区分:any vs unknown

  • any:完全绕过类型检查,赋值给任何变量都不报错(不推荐)。
  • unknown:类型安全的“任意类型”,需类型断言类型守卫后才能使用。

2. 复合类型

(1)数组类型
1
2
3
// 两种写法等价
let arr1: number[] = [1, 2, 3]
let arr2: Array<string> = ['a', 'b']
(2)元组(Tuple)

固定长度、固定类型的数组:

1
2
let tuple: [string, number] = ['TS', 10]
tuple[0] // 访问第一个元素(string)
(3)枚举(Enum)

定义一组命名常量:

1
2
3
4
5
6
7
8
9
10
11
12
13
// 数字枚举(默认从0开始)
enum Status {
Pending, // 0
Success, // 1
Failed // 2
}
let s: Status = Status.Success

// 字符串枚举
enum Color {
Red = 'red',
Blue = 'blue'
}

3. 接口(Interface)

定义对象的结构,是 TS 最核心的类型约束方式:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
// 基础接口
interface User {
id: number; // 必选属性
name: string;
age?: number; // 可选属性(?)
readonly email: string; // 只读属性(readonly)
}

// 函数类型接口
interface AddFn {
(a: number, b: number): number;
}
const add: AddFn = (a, b) => a + b

// 索引签名(动态属性)
interface Dict {
[key: string]: string; // key 是 string,value 是 string
}
const dict: Dict = { name: 'TS', version: '5.0' }

// 接口继承
interface Admin extends User {
role: string;
}

4. 类型别名(Type Aliases)

给类型起别名,可定义更复杂的类型(联合、交叉等):

1
2
3
4
5
6
7
8
9
10
11
12
// 基础类型别名
type ID = number | string

// 联合类型(|):满足其中一种类型
type Status = 'pending' | 'success' | 'failed'

// 交叉类型(&):同时满足多种类型
type Person = { name: string } & { age: number }

// 类型别名 vs 接口:
// - 接口:适合定义对象结构,支持继承、合并声明。
// - 类型别名:适合定义联合/交叉类型、工具类型。

三、函数类型

TS 对函数的参数、返回值都可做类型约束:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
// 基础函数类型
function greet(name: string): string {
return `Hello ${name}`
}

// 可选参数(?)、默认参数
function log(msg: string, level?: string): void {
console.log(level || 'info', msg)
}

// 剩余参数
function sum(...nums: number[]): number {
return nums.reduce((a, b) => a + b, 0)
}

// 函数重载(同一函数名,不同参数类型/数量)
function add(a: number, b: number): number;
function add(a: string, b: string): string;
function add(a: any, b: any): any {
return a + b
}

四、类(Class)

TS 增强了 JS 类的面向对象能力,支持访问修饰符、抽象类等:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
class Animal {
// 访问修饰符:public(默认)、private(仅类内)、protected(类内+子类)
private name: string;
protected age: number;

constructor(name: string, age: number) {
this.name = name;
this.age = age;
}

// 方法
public speak(): void {
console.log(`${this.name} makes noise`);
}
}

// 继承
class Dog extends Animal {
private breed: string;

constructor(name: string, age: number, breed: string) {
super(name, age); // 调用父类构造函数
this.breed = breed;
}

// 重写方法
public speak(): void {
console.log(`${this.name} barks`);
}
}

// 抽象类(不能实例化,需子类继承)
abstract class Shape {
abstract getArea(): number; // 抽象方法(子类必须实现)
}
class Circle extends Shape {
getArea() { return Math.PI * 10 * 10; }
}

五、泛型(Generics)

实现类型复用,让类型像参数一样传递,是 TS 高级特性的核心:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
// 泛型函数
function identity<T>(value: T): T {
return value;
}
identity<string>('TS') // 显式指定类型
identity(123) // 类型推断(推荐)

// 泛型接口
interface Box<T> {
value: T;
}
const box: Box<number> = { value: 100 }

// 泛型约束(限制泛型的范围)
interface Lengthwise {
length: number;
}
function logLength<T extends Lengthwise>(value: T): void {
console.log(value.length);
}
logLength('TS') // 字符串有 length,合法
logLength([1,2,3]) // 数组有 length,合法

六、高级类型工具

TS 内置了大量工具类型,用于快速转换类型(日常开发高频使用):

工具类型 作用 示例
Partial<T> 所有属性变为可选 Partial<User>
Required<T> 所有属性变为必选 Required<User>
Readonly<T> 所有属性变为只读 Readonly<User>
Pick<T, K> 从 T 中选取部分属性 K `Pick<User, ‘id’
Omit<T, K> 从 T 中排除部分属性 K Omit<User, 'email'>
Record<K, T> 定义 key 为 K、value 为 T 的对象 Record<string, number>
Exclude<T, U> 从 T 中排除属于 U 的类型 `Exclude<’a’
Extract<T, U> 从 T 中提取属于 U 的类型 `Extract<’a’
ReturnType<T> 获取函数返回值类型 ReturnType<typeof add>

示例:

1
2
3
4
5
6
7
8
9
interface User {
id: number;
name: string;
email: string;
}

// 只需要 id 和 name,排除 email
type UserPreview = Omit<User, 'email'>;
// 结果:{ id: number; name: string }

七、类型断言与守卫

1. 类型断言

告诉编译器“我比你更清楚类型”,有两种写法:

1
2
3
4
5
let val: unknown = 'TS'
// 写法1:as 语法(推荐)
let len: number = (val as string).length
// 写法2:尖括号语法(JSX 中不兼容)
let len2: number = (<string>val).length

2. 类型守卫

在运行时判断类型,让编译器自动缩小类型范围:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
// typeof 守卫(基础类型)
function isString(val: unknown): val is string {
return typeof val === 'string'
}

// instanceof 守卫(类)
function isDog(animal: Animal): animal is Dog {
return animal instanceof Dog
}

// in 守卫(对象属性)
function hasName(obj: any): obj is { name: string } {
return 'name' in obj
}

八、模块与声明文件

1. 模块系统

TS 支持 ES 模块(import/export),与 JS 一致:

1
2
3
4
5
6
// 导出
export const name = 'TS'
export function add(a: number, b: number) { return a + b }

// 导入
import { name, add } from './utils'

2. 声明文件(.d.ts

为第三方 JS 库提供类型支持(如 lodashjquery):

1
2
3
4
5
// 例如:声明全局变量
declare var $: (selector: string) => any;

// 社区已维护大量声明文件,通过 npm 安装:
// npm install @types/lodash --save-dev

九、配置文件:tsconfig.json

TS 项目的核心配置文件,控制编译行为:

1
2
3
4
5
6
7
8
9
10
11
12
13
{
"compilerOptions": {
"target": "ES6", // 编译目标 JS 版本
"module": "ESNext", // 模块系统
"strict": true, // 开启严格模式(推荐)
"esModuleInterop": true, // 兼容 CommonJS 模块
"outDir": "./dist", // 编译输出目录
"rootDir": "./src", // 源码目录
"skipLibCheck": true // 跳过声明文件检查
},
"include": ["src/**/*"], // 包含的文件
"exclude": ["node_modules"] // 排除的文件
}

十、最佳实践

  1. **尽量避免 any**:优先用 unknown,配合类型断言/守卫。
  2. 开启严格模式tsconfig.json"strict": true,强制类型安全。
  3. 合理使用工具类型:用 PartialPickOmit 等简化类型定义。
  4. 类型推断优先:TS 能自动推断的类型,无需显式声明(如 let name = 'TS' 不用写 : string)。
  5. 为第三方库安装类型声明:如 @types/lodash,避免类型缺失。

总结

TS 的核心是“类型安全 + 渐进式”,重点掌握:

  • 基础类型、接口、类型别名(构建类型系统的基础)。
  • 泛型、工具类型(实现类型复用的关键)。
  • 类型断言、守卫(处理复杂类型场景)。
  • 严格模式 + 合理配置(最大化 TS 价值)。

通过这些知识,可大幅提升代码的可维护性和可靠性,减少运行时错误。

补充

一、TypeScript 类型系统

TypeScript 类型系统的核心价值在于静态类型检查类型复用,通过类型约束提前发现潜在错误,提升代码的可维护性和可扩展性。

1. 泛型(Generics)

泛型是实现类型复用类型安全的核心工具,允许在定义函数、接口或类时不预先指定具体类型,而是在使用时动态传入,就像给类型“传参”。

核心语法与示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
// 1. 函数泛型:最常用场景,让函数返回值类型与输入类型关联
function identity<T>(arg: T): T {
return arg;
}
// 使用方式:显式传入类型 或 利用类型推断
const num = identity<number>(100); // 显式
const str = identity("hello"); // 类型推断

// 2. 接口泛型:定义通用的数据结构
interface ApiResponse<T> {
code: number;
data: T; // data 的类型由外部传入
message: string;
}
// 使用:定义不同业务场景的响应类型
interface UserData { id: number; name: string; }
const userRes: ApiResponse<UserData> = {
code: 200,
data: { id: 1, name: "张三" },
message: "success"
};

// 3. 泛型约束:限制泛型的类型范围
interface Lengthwise { length: number; }
function logLength<T extends Lengthwise>(arg: T): void {
console.log(arg.length); // 必须有 length 属性
}

2. 联合类型 / 交叉类型

这是 TypeScript 中类型组合的两种核心方式,用于从现有类型构建新类型。

联合类型(Union Types):|

表示“或”的关系,值可以是多种类型中的一种。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
// 基础用法
let value: string | number;
value = "hello"; // 合法
value = 100; // 合法

// 典型场景:处理不同状态的返回值
interface Success { status: "success"; data: string; }
interface Error { status: "error"; message: string; }
type Result = Success | Error;

function handleResult(res: Result) {
// 结合类型守卫使用(见下文)
if (res.status === "success") {
console.log(res.data); // 此时 res 自动收窄为 Success 类型
} else {
console.log(res.message); // 此时 res 自动收窄为 Error 类型
}
}

交叉类型(Intersection Types):&

表示“且”的关系,将多个类型的属性合并为一个新类型。

1
2
3
4
5
6
7
8
9
// 基础用法
interface Person { name: string; }
interface Employee { id: number; }
type Worker = Person & Employee;

const worker: Worker = {
name: "李四",
id: 1001 // 必须同时拥有两个接口的所有属性
};

3. 类型守卫(Type Guards)

类型守卫是在运行时收窄类型范围的机制,让 TypeScript 在编译时就能准确推断出变量的具体类型,避免大量的类型断言。

常用类型守卫方式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
// 1. typeof 类型守卫:适用于基本类型
function processValue(val: string | number) {
if (typeof val === "string") {
return val.toUpperCase(); // 此时 val 是 string
}
return val.toFixed(2); // 此时 val 是 number
}

// 2. instanceof 类型守卫:适用于类实例
class Dog { bark() {} }
class Cat { meow() {} }
function makeSound(animal: Dog | Cat) {
if (animal instanceof Dog) {
animal.bark();
} else {
animal.meow();
}
}

// 3. in 操作符类型守卫:适用于对象属性
interface Car { drive(): void; }
interface Plane { fly(): void; }
function move(vehicle: Car | Plane) {
if ("drive" in vehicle) {
vehicle.drive();
} else {
vehicle.fly();
}
}

// 4. 自定义类型守卫(is 关键字):最灵活的方式
interface Fish { swim: boolean; }
interface Bird { fly: boolean; }
// 自定义守卫函数,返回值是类型谓词 parameterName is Type
function isFish(animal: Fish | Bird): animal is Fish {
return (animal as Fish).swim !== undefined;
}
function moveAnimal(animal: Fish | Bird) {
if (isFish(animal)) {
console.log("Swimming");
} else {
console.log("Flying");
}
}

Typescript开发重点
https://cszy.top/20250507-Typescript开发重点/
作者
csorz
发布于
2025年5月7日
许可协议