TypeScript 入门手册——从 JavaScript 到 TypeScript

TypeScript 入门手册——从 JavaScript 到 TypeScript

作者: CaoZH
日期: 2022-12-15
本文为原创教程


TypeScript 在 2022 年已经成为前端开发的标配语言。Vue 3、React、Next.js、Nuxt 等主流框架全面拥抱 TypeScript,如果你还在纯 JavaScript 开发,是时候升级了。

本文从 JavaScript 开发者的角度出发,带你快速掌握 TypeScript 的核心概念。

一、TypeScript 是什么?

TypeScript = JavaScript + 类型系统

TypeScript 是微软开发的开源编程语言,是 JavaScript 的超集——合法的 JavaScript 代码就是合法的 TypeScript 代码。它在编译时进行类型检查,最终编译为纯 JavaScript 运行。

为什么要用 TypeScript?

对比 JavaScript TypeScript
类型检查 运行时才发现 编译时就发现
IDE 提示 有限 完整的自动补全和类型提示
重构 容易改漏 类型系统保障安全
文档 需要手写注释 类型即文档
Bug 发现 上线后才发现 开发阶段就发现

据统计,TypeScript 可以在开发阶段捕获 15%~20% 的 JavaScript 常见 bug。

二、安装与配置

1
2
3
4
5
6
7
8
9
10
11
# 全局安装
npm install -g typescript

# 验证版本
tsc --version

# 编译 TypeScript 文件
tsc hello.ts # 输出 hello.js

# 生成 tsconfig.json
tsc --init

tsconfig.json 基础配置

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

三、类型基础

基本类型

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
// 字符串
let name: string = 'TypeScript';

// 数字
let age: number = 28;
let price: number = 99.9;

// 布尔值
let isDone: boolean = false;

// 数组
let list: number[] = [1, 2, 3];
let items: Array<string> = ['a', 'b']; // 泛型写法

// 元组(固定长度数组)
let pair: [string, number] = ['age', 28];

// 枚举
enum Color { Red, Green, Blue }
let c: Color = Color.Green; // 1

// 任意值(尽量少用)
let notSure: any = 4;
notSure = 'maybe a string';

// 空值
function log(msg: string): void {
console.log(msg);
}

接口(Interface)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
interface User {
id: number;
name: string;
email: string;
age?: number; // 可选属性
readonly createdAt: Date; // 只读属性
}

const user: User = {
id: 1,
name: '张三',
email: 'zhangsan@example.com',
createdAt: new Date()
};

// 接口扩展
interface Admin extends User {
role: 'admin' | 'superadmin';
permissions: string[];
}

类型别名(Type)

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

// 联合类型
type Status = 'active' | 'inactive' | 'deleted';

// 交叉类型
type Person = { name: string } & { age: number };

// 函数类型
type Callback = (error: Error | null, result: any) => void;

Interface vs Type

1
2
3
4
5
6
7
8
9
// Interface 可以合并声明
interface User { name: string; }
interface User { age: number; } // ✅ 合并

// Type 不可以
type User = { name: string; };
type User = { age: number; }; // ❌ 重复定义

// 建议:定义对象用 Interface,定义联合类型用 Type

四、函数类型

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
// 函数声明
function add(a: number, b: number): number {
return a + b;
}

// 箭头函数
const multiply = (a: number, b: number): number => a * b;

// 可选参数
function greet(name: string, title?: string): string {
return title ? `${title} ${name}` : name;
}

// 默认参数
function createUser(name: string, age: number = 18): User {
return { id: Date.now(), name, age, createdAt: new Date() };
}

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

// 函数重载
function parse(input: string): string[];
function parse(input: number): number;
function parse(input: string | number): string[] | number {
if (typeof input === 'string') return input.split(',');
return input;
}

五、泛型(Generics)

泛型是 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
// 泛型函数
function identity<T>(arg: T): T {
return arg;
}

const result = identity<string>('hello');
const result2 = identity(42); // 类型推断

// 泛型接口
interface ApiResponse<T> {
code: number;
message: string;
data: T;
}

// 使用
type UserResponse = ApiResponse<User>;
type ListResponse = ApiResponse<User[]>;

// 泛型约束
function getLength<T extends { length: number }>(arg: T): number {
return arg.length;
}

getLength('hello'); // ✅ 5
getLength([1, 2, 3]); // ✅ 3
// getLength(123); // ❌ number 没有 length

六、实战:一个简单的 API 封装

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
45
46
47
48
// api.ts
import axios, { AxiosInstance } from 'axios';

interface ApiConfig {
baseURL: string;
timeout?: number;
}

interface ApiResponse<T> {
code: number;
msg: string;
data: T;
}

class ApiClient {
private client: AxiosInstance;

constructor(config: ApiConfig) {
this.client = axios.create({
baseURL: config.baseURL,
timeout: config.timeout ?? 10000,
});
}

async get<T>(url: string, params?: Record<string, any>): Promise<ApiResponse<T>> {
const { data } = await this.client.get<ApiResponse<T>>(url, { params });
return data;
}

async post<T>(url: string, body: any): Promise<ApiResponse<T>> {
const { data } = await this.client.post<ApiResponse<T>>(url, body);
return data;
}
}

// 使用
interface User {
id: number;
name: string;
email: string;
}

const api = new ApiClient({ baseURL: 'https://api.example.com' });

async function getUser(id: number) {
const res = await api.get<User>(`/users/${id}`);
console.log(res.data.name); // 有完整的类型提示 ✅
}

七、总结

TypeScript 的学习曲线并不陡峭。你完全可以先当 JavaScript 用(把所有 .js 改成 .ts,遇到报错再逐步加类型),慢慢你会发现类型系统带来的好处远超你付出的那点成本。

推荐学习路径:

  1. ✅ 基础类型 + 接口(本周就能用上)
  2. ✅ 泛型(做工具函数时用到)
  3. ✅ 类型工具(Partial、Pick、Omit 等)
  4. ✅ 声明文件(给别人用的库需要)
  5. ✅ 条件类型 + 映射类型(进阶用法)

首发于 CaoZH 的笔记