【TypeScript】TypeScript的应用实例
目录
一、TypeScript 简介
二、快速开始
1. 安装 TypeScript
2. 编写第一个 TypeScript 文件
3. 编译并运行
三、TypeScript基础
四、TypeScript 配置(tsconfig.json)
五、在 React 框架中使用
六、常见问题
Q1: TypeScript 和 JavaScript 有什么区别?
Q2: 如何处理第三方库没有类型定义?
Q3: 如何逐步迁移 JavaScript 项目到 TypeScript?
七、应用
1.前端应用
1.类型安全的组件Props
2. 状态管理(Redux + TypeScript)
2.后端应用
1.类型安全的Express路由
2. 数据库操作(TypeORM + TypeScript)
3.通用工具开发
1. 类型安全的配置管理
2.泛型工具函数
4.高级类型操作
1.类型守卫(TypeGuard)
2.条件类型与映射类型
5。测试与调试
1.类型安全的测试(Jest + TypeScript)
6.常见场景解决方案
1.处理第三方库无类型定义
2.动态属性对象
7.资源推荐
一、TypeScript 简介
是什么:TypeScript 是 JavaScript 的超集,添加了静态类型系统。
优势:
类型检查:在编码阶段发现潜在错误。
更好的代码提示:IDE 智能补全。
适合大型项目:代码可维护性高。
环境要求:Node.js(建议 v14+)
二、快速开始
1. 安装 TypeScript
npm install -g typescript # 全局安装编译器
tsc --version # 查看版本
2. 编写第一个 TypeScript 文件
新建 hello.ts
:
function greet(name: string): void {
console.log(`Hello, ${name}!`);
}
greet("World");
3. 编译并运行
tsc hello.ts # 生成 hello.js
node hello.js # 输出 "Hello, World!"
三、TypeScript基础
本文在此简单介绍TypeScript相关基础,关于TypeScript更详细基础知识点可观看博主前端基础的 TypeScript相关博文。
1.基础类型
let isDone: boolean = false;
let count: number = 42;
let name: string = "Alice";
// 数组
let list: number[] = [1, 2, 3];
let words: Array<string> = ["hello", "world"];
// 元组(固定长度和类型)
let tuple: [string, number] = ["Alice", 30];
// 枚举
enum Color { Red, Green, Blue }
let c: Color = Color.Green;
// any 和 unknown
let notSure: any = 4;
notSure = "maybe a string";
// void(函数无返回值)
function log(): void {
console.log("No return");
}
2.接口(Interface)
定义对象的结构
interface User {
name: string;
age: number;
email?: string; // 可选属性
}
function printUser(user: User): void {
console.log(`Name: ${user.name}, Age: ${user.age}`);
}
const alice: User = { name: "Alice", age: 30 };
printUser(alice);
3.类(class)
面向对象编程支持
class Animal {
private name: string; // 私有属性
constructor(name: string) {
this.name = name;
}
public move(distance: number = 0): void {
console.log(`${this.name} moved ${distance}m.`);
}
}
class Dog extends Animal {
bark(): void {
console.log("Woof! Woof!");
}
}
const dog = new Dog("Buddy");
dog.move(10); // 输出 "Buddy moved 10m."
dog.bark();
4.函数类型
定义函数参数和返回值的类型
// 函数类型注解
type AddFunc = (a: number, b: number) => number;
const add: AddFunc = (a, b) => a + b;
console.log(add(2, 3)); // 5
// 可选参数和默认参数
function greet(name: string, greeting: string = "Hello"): string {
return `${greeting}, ${name}!`;
}
console.log(greet("Alice")); // "Hello, Alice!"
5.泛型(Generics)
编写可复用的类型安全代码
// 泛型函数
function identity<T>(arg: T): T {
return arg;
}
let output = identity<string>("hello"); // 显式指定类型
let output2 = identity(42); // 类型推断为 number
// 泛型接口
interface KeyValuePair<K, V> {
key: K;
value: V;
}
const pair: KeyValuePair<number, string> = { key: 1, value: "Apple" };
6.联合类型与类型守卫
处理多种可能得类型
// 联合类型
type ID = string | number;
function printId(id: ID) {
if (typeof id === "string") {
console.log(`ID is a string: ${id.toUpperCase()}`);
} else {
console.log(`ID is a number: ${id.toFixed(2)}`);
}
}
printId("abc123"); // "ID is a string: ABC123"
printId(3.1415); // "ID is a number: 3.14"
四、TypeScript 配置(tsconfig.json)
通过配置文件定制编译选项
{
"compilerOptions": {
"target": "ES6", // 编译目标版本
"module": "CommonJS", // 模块系统
"strict": true, // 启用严格模式
"outDir": "./dist", // 输出目录
"esModuleInterop": true // 兼容 CommonJS/ES6 模块
},
"include": ["src/**/*.ts"], // 包含的文件
"exclude": ["node_modules"]
}
五、在 React 框架的使用
更详细使用方法见【react】TypeScript在react中的使用
// 组件 Props 和 State 的类型定义
interface CounterProps {
initialCount: number;
}
interface CounterState {
count: number;
}
class Counter extends React.Component<CounterProps, CounterState> {
state: CounterState = {
count: this.props.initialCount,
};
increment = () => {
this.setState({ count: this.state.count + 1 });
};
render() {
return (
<div>
<p>Count: {this.state.count}</p>
<button onClick={this.increment}>Increment</button>
</div>
);
}
}
// 函数组件示例
type ButtonProps = {
onClick: () => void;
children: React.ReactNode;
};
const Button: React.FC<ButtonProps> = ({ onClick, children }) => (
<button onClick={onClick}>{children}</button>
);
六、常见问题
Q1: TypeScript 和 JavaScript 有什么区别?
-
TypeScript 是静态类型语言,编译阶段检查类型错误;JavaScript 是动态类型语言。
Q2: 如何处理第三方库没有类型定义?
-
安装社区维护的类型包:
npm install @types/library-name
。 -
或手动声明:创建
.d.ts
文件,使用declare module 'library-name';
Q3: 如何逐步迁移 JavaScript 项目到 TypeScript?
-
将文件后缀改为
.ts
并修复类型错误。 -
配置
tsconfig.json
的allowJs: true
以混合编译
七、应用
1.前端应用
1.类型安全的组件Props
interface ButtonProps {
children: React.ReactNode;
onClick: () => void;
variant?: "primary" | "secondary"; // 可选参数,限定可选值
disabled?: boolean;
}
const Button: React.FC<ButtonProps> = ({
children,
onClick,
variant = "primary",
disabled = false
}) => {
return (
<button
className={`btn-${variant}`}
onClick={onClick}
disabled={disabled}
>
{children}
</button>
);
};
// 使用组件时,IDE 会提示 Props 类型
<Button variant="primary" onClick={() => console.log("Clicked")}>
Submit
</Button>
2. 状态管理(Redux + TypeScript)
// 定义 Action 类型
type CounterAction =
| { type: 'INCREMENT'; payload: number }
| { type: 'DECREMENT'; payload: number };
// 定义 State 类型
interface CounterState {
count: number;
}
// Reducer 函数
const counterReducer = (
state: CounterState = { count: 0 },
action: CounterAction
): CounterState => {
switch (action.type) {
case 'INCREMENT':
return { count: state.count + action.payload };
case 'DECREMENT':
return { count: state.count - action.payload };
default:
return state;
}
};
2.后端应用
1.类型安全的Express路由
import express, { Request, Response } from 'express';
interface User {
id: number;
name: string;
email: string;
}
const app = express();
app.use(express.json());
// GET /users/:id
app.get('/users/:id', (req: Request<{ id: string }>, res: Response<User>) => {
const userId = parseInt(req.params.id);
const user: User = { id: userId, name: "Alice", email: "alice@example.com" };
res.json(user); // 自动校验返回类型是否符合 User
});
// POST /users
app.post('/users', (req: Request<{}, {}, User>, res: Response<{ success: boolean }>) => {
const newUser = req.body; // 自动推断为 User 类型
console.log("Creating user:", newUser);
res.json({ success: true });
});
2. 数据库操作(TypeORM + TypeScript)
import { Entity, PrimaryGeneratedColumn, Column, BaseEntity } from 'typeorm';
@Entity()
class User extends BaseEntity {
@PrimaryGeneratedColumn()
id: number;
@Column()
name: string;
@Column({ unique: true })
email: string;
static async findByName(name: string): Promise<User | undefined> {
return this.findOne({ where: { name } });
}
}
// 使用
const user = await User.findByName("Alice");
3.通用工具开发
1. 类型安全的配置管理
interface AppConfig {
port: number;
db: {
host: string;
username: string;
password: string;
};
env: "development" | "production";
}
const loadConfig = (): AppConfig => {
return {
port: process.env.PORT ? parseInt(process.env.PORT) : 3000,
db: {
host: process.env.DB_HOST || "localhost",
username: process.env.DB_USER || "root",
password: process.env.DB_PASSWORD || "",
},
env: process.env.NODE_ENV === "production" ? "production" : "development",
};
};
const config = loadConfig();
console.log(config.db.host); // 类型安全访问
2.泛型工具函数
// 分页查询响应类型
interface PaginatedResponse<T> {
data: T[];
page: number;
total: number;
}
// 泛型函数:模拟 API 分页
function paginate<T>(items: T[], page: number, pageSize: number): PaginatedResponse<T> {
const start = (page - 1) * pageSize;
const end = start + pageSize;
return {
data: items.slice(start, end),
page,
total: items.length,
};
}
// 使用
const users = [{ id: 1, name: "Alice" }, { id: 2, name: "Bob" }];
const result = paginate(users, 1, 1); // result.data 类型自动推断为 User[]
4.高级类型操作
1.类型守卫(TypeGuard)
interface Cat {
type: "cat";
meow: () => void;
}
interface Dog {
type: "dog";
bark: () => void;
}
type Animal = Cat | Dog;
function handleAnimal(animal: Animal) {
if (animal.type === "cat") {
animal.meow(); // TypeScript 知道此时是 Cat 类型
} else {
animal.bark(); // 自动推断为 Dog 类型
}
}
2.条件类型与映射类型
// 将对象所有属性变为可选
type PartialAll<T> = {
[K in keyof T]?: T[K];
};
// 条件类型:提取函数返回值类型
type ReturnType<T> = T extends (...args: any[]) => infer R ? R : never;
// 使用
function add(a: number, b: number): number { return a + b; }
type AddReturn = ReturnType<typeof add>; // number
5。测试与调试
1.类型安全的测试(Jest + TypeScript)
// 测试工具函数
function sum(a: number, b: number): number {
return a + b;
}
describe('sum function', () => {
it('correctly adds two numbers', () => {
expect(sum(2, 3)).toBe(5); // 类型检查参数和返回值
});
it('rejects non-number inputs', () => {
// @ts-expect-error - 故意传入错误类型测试类型安全
expect(sum("2", 3)).toThrow();
});
});
6.常见场景解决方案
1.处理第三方库无类型定义
// 创建 declarations.d.ts
declare module 'untyped-library' {
export function doSomething(config: any): void;
}
// 使用
import { doSomething } from 'untyped-library';
doSomething({ key: "value" }); // 暂时用 any,后续补充完整类型
2.动态属性对象
interface DynamicObject {
[key: string]: string | number;
}
const obj: DynamicObject = {
name: "Alice",
age: 30,
// 以下会报错
// isAdmin: true
};
7.资源推荐
-
TypeScript Playground:在线实验 TypeScript 代码
-
Utility Types 文档:官方工具类型
-
DefinitelyTyped:第三方库类型定义仓库
码字不易,各位大佬点点赞呗