vault backup: 2026-04-24 23:45:19
This commit is contained in:
@@ -0,0 +1,156 @@
|
||||
---
|
||||
tags: [前端, TypeScript, 基础]
|
||||
create time: 2026-04-24 18:41
|
||||
---
|
||||
|
||||
# TypeScript 基础
|
||||
|
||||
## 概述
|
||||
|
||||
TypeScript 是 JavaScript 的超集,在 JS 的基础上增加了类型系统。它的核心理念:**用类型在编译阶段捕获错误,而不是在运行时才发现 bug。**
|
||||
|
||||
思考题:JavaScript 是动态类型语言,TypeScript 是静态类型语言——它们到底有什么区别?为什么大型前端项目必须用 TypeScript?
|
||||
|
||||
## 正文
|
||||
|
||||
### 1. 类型注解
|
||||
|
||||
```typescript
|
||||
// 基本类型注解
|
||||
let userName: string = "Alice";
|
||||
let age: number = 25;
|
||||
let isActive: boolean = true;
|
||||
let scores: number[] = [90, 85, 92]; // 数组
|
||||
let tuple: [string, number] = ["Alice", 25]; // 元组
|
||||
|
||||
// 对象类型
|
||||
interface User {
|
||||
name: string;
|
||||
age: number;
|
||||
email?: string; // ? 表示可选属性
|
||||
}
|
||||
|
||||
const user: User = {
|
||||
name: "Alice",
|
||||
age: 25,
|
||||
email: "alice@example.com",
|
||||
};
|
||||
```
|
||||
|
||||
> **提问:** `string` 和 `String`(首字母小写 vs 大写)有什么区别?为什么 TS 用小写?
|
||||
|
||||
### 2. 联合类型与类型守卫
|
||||
|
||||
```typescript
|
||||
// 联合类型:一个变量可以是多种类型
|
||||
let value: string | number = "hello";
|
||||
value = 42; // ✅ 合法
|
||||
value = true; // ❌ 编译错误
|
||||
|
||||
// 类型守卫:在运行时判断具体类型
|
||||
function processValue(input: string | number) {
|
||||
if (typeof input === "string") {
|
||||
return input.toUpperCase(); // TS 知道这里是 string
|
||||
}
|
||||
return input.toFixed(2); // TS 知道这里是 number
|
||||
}
|
||||
|
||||
// 自定义类型守卫
|
||||
function isUser(obj: unknown): obj is User {
|
||||
return typeof obj === "object" && obj !== null && "name" in obj;
|
||||
}
|
||||
```
|
||||
|
||||
### 3. 接口(Interface)vs 类型别名(Type Alias)
|
||||
|
||||
```typescript
|
||||
// Interface:适合定义对象形状,可扩展
|
||||
interface Animal {
|
||||
name: string;
|
||||
}
|
||||
|
||||
interface Dog extends Animal {
|
||||
breed: string;
|
||||
}
|
||||
|
||||
// Type Alias:更灵活,可用于联合类型、元组等
|
||||
type ID = string | number;
|
||||
type Point = [number, number];
|
||||
type EventHandler = (event: MouseEvent) => void;
|
||||
```
|
||||
|
||||
> **核心区别:** Interface 可以被合并(declaration merging),Type Alias 不能。定义对象形状优先用 Interface,复杂类型用 Type。
|
||||
|
||||
### 4. 泛型(Generics)
|
||||
|
||||
```typescript
|
||||
// 泛型函数:类型参数化
|
||||
function identity<T>(arg: T): T {
|
||||
return arg;
|
||||
}
|
||||
|
||||
identity<string>("hello"); // 返回 string
|
||||
identity<number>(42); // 返回 number
|
||||
|
||||
// 泛型接口:React Props 的典型模式
|
||||
interface ApiResponse<T> {
|
||||
data: T;
|
||||
status: number;
|
||||
message: string;
|
||||
}
|
||||
|
||||
// 实际使用
|
||||
const response: ApiResponse<User[]> = {
|
||||
data: [{ name: "Alice", age: 25 }],
|
||||
status: 200,
|
||||
message: "success",
|
||||
};
|
||||
```
|
||||
|
||||
> **思考:** 为什么 React 组件的 Props 要用泛型?泛型如何让组件在复用时代码类型安全?
|
||||
|
||||
### 5. TS + React 实战示例
|
||||
|
||||
```typescript
|
||||
// 定义 Props 接口
|
||||
interface CounterProps {
|
||||
initialCount?: number;
|
||||
step?: number;
|
||||
onCountChange?: (count: number) => void;
|
||||
}
|
||||
|
||||
// 带泛型的 API 响应组件
|
||||
interface DataResponse<T> {
|
||||
data: T | null;
|
||||
loading: boolean;
|
||||
error: string | null;
|
||||
}
|
||||
|
||||
// 组件实现
|
||||
const Counter: React.FC<CounterProps> = ({
|
||||
initialCount = 0,
|
||||
step = 1,
|
||||
onCountChange,
|
||||
}) => {
|
||||
const [count, setCount] = useState(initialCount);
|
||||
|
||||
const increment = () => {
|
||||
const newCount = count + step;
|
||||
setCount(newCount);
|
||||
onCountChange?.(newCount);
|
||||
};
|
||||
|
||||
return (
|
||||
<div>
|
||||
<span>Count: {count}</span>
|
||||
<button onClick={increment}>+{step}</button>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
```
|
||||
|
||||
## 关联笔记
|
||||
|
||||
- [[JavaScript 基础]] — TypeScript 基于 JavaScript,TS 类型系统是对 JS 的增强
|
||||
- [[CSS 基础]] — TS 项目中常用的样式方案
|
||||
- [[30.areas/finance/Investment lessons/2024.Current trading lessons.md]]
|
||||
Reference in New Issue
Block a user