TypeScript 入门指南:从 JavaScript 到类型安全
TypeScript是JavaScript的超集,通过静态类型系统为大型项目提供更好的代码质量保障。目前已成为前端开发和Node.js后端开发的主流选择。本文带你快速入门TypeScript核心特性。
一、为什么使用TypeScript
- 类型安全:在编译阶段捕获类型错误,而不是在运行时崩溃
- 智能提示:IDE提供精准的代码补全、参数提示、文档提示
- 重构友好:类型系统保障大规模重构的安全性
- 更好的文档:类型声明本身就是最好的文档
- 渐进迁移:可以将现有JavaScript项目逐步迁移到TypeScript
二、基础类型
// 基本类型
let name: string = "Alice";
let age: number = 25;
let isActive: boolean = true;
let nothing: null = null;
let undef: undefined = undefined;
// 数组类型
let numbers: number[] = [1, 2, 3];
let strings: Array<string> = ["a", "b", "c"];
// 元组(固定长度和类型的数组)
let pair: [string, number] = ["age", 25];
// 枚举
enum Direction { Up, Down, Left, Right }
let dir: Direction = Direction.Up;
// Any(绕过类型检查,尽量避免使用)
let anything: any = "could be anything";
// Unknown(比any更安全)
let userInput: unknown = "hello";
if (typeof userInput === "string") {
console.log(userInput.toUpperCase()); // 类型守卫后才能使用
}
// Union类型(联合类型)
let id: string | number = "user-001";
id = 123; // 也合法
// Literal类型(字面量类型)
let direction: "north" | "south" | "east" | "west" = "north";
三、接口与类型别名
// Interface:定义对象结构
interface User {
id: number;
name: string;
email?: string; // 可选属性
readonly createdAt: Date; // 只读属性
}
// 类型别名(Type Alias)
type Point = {
x: number;
y: number;
};
// 接口继承
interface Admin extends User {
role: "super" | "normal";
permissions: string[];
}
// 函数类型
interface Transformer<T, U> {
(input: T): U;
}
const toString: Transformer<number, string> = (n) => n.toString();
四、泛型(Generics)
// 泛型函数
function identity<T>(value: T): T {
return value;
}
const num = identity<number>(42); // 显式指定
const str = identity("hello"); // 类型推断
// 泛型约束
interface HasLength {
length: number;
}
function getLength<T extends HasLength>(item: T): number {
return item.length;
}
// 泛型类
class Stack<T> {
private items: T[] = [];
push(item: T): void { this.items.push(item); }
pop(): T | undefined { return this.items.pop(); }
isEmpty(): boolean { return this.items.length === 0; }
}
const numStack = new Stack<number>();
numStack.push(1);
numStack.push(2);
五、高级类型
// Partial:所有属性变为可选
type PartialUser = Partial<User>; // { id?: number; name?: string; ... }
// Required:所有属性变为必填
type RequiredUser = Required<User>;
// Pick:选取部分属性
type UserPreview = Pick<User, "id" | "name">;
// Omit:排除部分属性
type UserWithoutId = Omit<User, "id">;
// Record:创建键值类型的对象
type UserMap = Record<string, User>;
// Conditional类型
type IsString<T> = T extends string ? true : false;
type R1 = IsString<string>; // true
type R2 = IsString<number>; // false
六、装饰器(Decorators)
// 类装饰器
function Singleton<T extends { new (...args: any[]): {} }>(cls: T) {
let instance: T;
return class extends cls {
constructor(...args: any[]) {
if (!instance) {
super(...args);
instance = this as any;
}
return instance;
}
};
}
// 方法装饰器(常用于日志、缓存、权限控制)
function log(target: any, key: string, descriptor: PropertyDescriptor) {
const original = descriptor.value;
descriptor.value = function (...args: any[]) {
console.log(`Calling ${key} with`, args);
const result = original.apply(this, args);
console.log(`${key} returned`, result);
return result;
};
return descriptor;
}
七、配置tsconfig.json
{
"compilerOptions": {
"target": "ES2020",
"module": "commonjs",
"strict": true, // 开启所有严格模式检查
"noImplicitAny": true, // 禁止隐式any
"strictNullChecks": true, // null和undefined需要显式处理
"outDir": "./dist",
"rootDir": "./src",
"declaration": true, // 生成.d.ts类型声明文件
"esModuleInterop": true,
"resolveJsonModule": true
},
"include": ["src/**/*"],
"exclude": ["node_modules", "dist"]
}
八、总结
TypeScript的学习曲线不陡峭,基础类型和接口可以在几小时内掌握。建议从现有JavaScript项目的入口文件开始,逐步添加类型注解,体验类型系统带来的红利。对于新项目,直接使用TypeScript是目前最佳实践,可以从项目初期就享受类型安全的保障。