文章目录
- [TypeScript 基础类型与接口详解](#TypeScript 基础类型与接口详解)
-
- 前言
- 目录
- [TypeScript 基础类型](#TypeScript 基础类型)
-
- [1. 基本类型](#1. 基本类型)
- [2. 数组类型](#2. 数组类型)
-
- [Array 类型](#Array 类型)
- 元组(Tuple)
- [3. 枚举(Enum)](#3. 枚举(Enum))
- [4. 特殊类型](#4. 特殊类型)
-
- any(任意类型)
- void(空值)
- [null 和 undefined](#null 和 undefined)
- never(永不存在的值)
- object(对象类型)
- 接口(Interface)详解
-
- [1. 基本接口定义](#1. 基本接口定义)
- [2. 可选属性](#2. 可选属性)
- [3. 只读属性](#3. 只读属性)
- [4. 函数类型接口](#4. 函数类型接口)
- [5. 可索引类型接口](#5. 可索引类型接口)
- [6. 类类型接口](#6. 类类型接口)
- 接口的高级特性
-
- [1. 继承接口](#1. 继承接口)
- [2. 混合类型接口](#2. 混合类型接口)
- [3. 接口合并](#3. 接口合并)
- 实际应用场景
-
- [1. API 响应类型定义](#1. API 响应类型定义)
- [2. 组件 Props 类型定义](#2. 组件 Props 类型定义)
- [3. 状态管理类型定义](#3. 状态管理类型定义)
- 最佳实践
-
- [1. 命名规范](#1. 命名规范)
- [2. 优先使用接口而不是类型别名](#2. 优先使用接口而不是类型别名)
- [3. 合理使用可选属性](#3. 合理使用可选属性)
- [4. 使用泛型增强复用性](#4. 使用泛型增强复用性)
- [5. 避免过度使用 any](#5. 避免过度使用 any)
- 总结
TypeScript 基础类型与接口详解
深入理解 TypeScript 的类型系统,掌握接口的使用技巧
前言
TypeScript 作为 JavaScript 的超集,为前端开发带来了强类型系统的优势。本文将深入讲解 TypeScript 的基础类型和接口,帮助开发者更好地理解和使用 TypeScript 的类型系统。
目录
- [TypeScript 基础类型](#TypeScript 基础类型)
- 接口(Interface)详解
- 接口的高级特性
- 实际应用场景
- 最佳实践
TypeScript 基础类型
1. 基本类型
string(字符串)
typescript
let name: string = "张三";
let message: string = `Hello, ${name}!`;
number(数字)
typescript
let age: number = 25;
let price: number = 99.99;
let binary: number = 0b1010; // 二进制
let octal: number = 0o744; // 八进制
let hex: number = 0xf00d; // 十六进制
boolean(布尔值)
typescript
let isActive: boolean = true;
let isCompleted: boolean = false;
2. 数组类型
Array 类型
typescript
// 方式一:类型[]
let numbers: number[] = [1, 2, 3, 4, 5];
let names: string[] = ["Alice", "Bob", "Charlie"];
// 方式二:Array<类型>
let scores: Array<number> = [85, 92, 78, 96];
let cities: Array<string> = ["北京", "上海", "深圳"];
元组(Tuple)
typescript
// 元组类型允许表示一个已知元素数量和类型的数组
let person: [string, number] = ["张三", 25];
let coordinate: [number, number] = [10, 20];
// 访问元组元素
console.log(person[0]); // "张三"
console.log(person[1]); // 25
// 元组越界访问会报错
// person[2] = "error"; // Error: Tuple type '[string, number]' of length '2' has no element at index '2'
3. 枚举(Enum)
数字枚举
typescript
enum Direction {
Up, // 0
Down, // 1
Left, // 2
Right // 3
}
let dir: Direction = Direction.Up;
console.log(dir); // 0
// 自定义起始值
enum Status {
Pending = 1,
Approved, // 2
Rejected // 3
}
字符串枚举
typescript
enum Color {
Red = "red",
Green = "green",
Blue = "blue"
}
let favoriteColor: Color = Color.Red;
console.log(favoriteColor); // "red"
常量枚举
typescript
const enum HttpStatus {
OK = 200,
NotFound = 404,
InternalServerError = 500
}
let status: HttpStatus = HttpStatus.OK;
4. 特殊类型
any(任意类型)
typescript
let value: any = 42;
value = "hello"; // OK
value = true; // OK
value = { x: 1 }; // OK
// 注意:过度使用 any 会失去 TypeScript 的类型检查优势
void(空值)
typescript
function logMessage(message: string): void {
console.log(message);
// 不返回任何值
}
let unusable: void = undefined; // void 类型的变量只能赋值 undefined
null 和 undefined
typescript
let n: null = null;
let u: undefined = undefined;
// 在严格模式下,null 和 undefined 只能赋值给自己
let name: string | null = null; // 联合类型
let age: number | undefined = undefined;
never(永不存在的值)
typescript
// 返回 never 的函数必须存在无法达到的终点
function error(message: string): never {
throw new Error(message);
}
function infiniteLoop(): never {
while (true) {
// 无限循环
}
}
object(对象类型)
typescript
let obj: object = { name: "张三", age: 25 };
// 更具体的对象类型定义
let person: { name: string; age: number } = {
name: "李四",
age: 30
};
接口(Interface)详解
1. 基本接口定义
接口是 TypeScript 的核心特性之一,用于定义对象的结构。
typescript
interface User {
id: number;
name: string;
email: string;
}
let user: User = {
id: 1,
name: "张三",
email: "zhangsan@example.com"
};
2. 可选属性
使用 ? 标记可选属性:
typescript
interface Product {
id: number;
name: string;
description?: string; // 可选属性
price: number;
category?: string; // 可选属性
}
let product1: Product = {
id: 1,
name: "笔记本电脑",
price: 5999
}; // OK,可选属性可以不提供
let product2: Product = {
id: 2,
name: "手机",
description: "最新款智能手机",
price: 3999,
category: "电子产品"
}; // OK,提供可选属性也没问题
3. 只读属性
使用 readonly 标记只读属性:
typescript
interface Config {
readonly apiUrl: string;
readonly timeout: number;
retries?: number;
}
let config: Config = {
apiUrl: "https://api.example.com",
timeout: 5000,
retries: 3
};
// config.apiUrl = "https://new-api.com"; // Error: Cannot assign to 'apiUrl' because it is a read-only property
4. 函数类型接口
接口可以描述函数类型:
typescript
interface SearchFunc {
(source: string, subString: string): boolean;
}
let mySearch: SearchFunc = function(source: string, subString: string): boolean {
return source.search(subString) > -1;
};
// 或者使用箭头函数
let mySearch2: SearchFunc = (src, sub) => {
return src.search(sub) > -1;
};
5. 可索引类型接口
描述可以通过索引访问的类型:
typescript
// 字符串索引签名
interface StringArray {
[index: number]: string;
}
let myArray: StringArray = ["Alice", "Bob"];
let myStr: string = myArray[0];
// 字符串索引签名
interface StringDictionary {
[key: string]: string;
}
let myDict: StringDictionary = {
name: "张三",
city: "北京"
};
6. 类类型接口
接口可以明确地强制一个类去符合某种契约:
typescript
interface ClockInterface {
currentTime: Date;
setTime(d: Date): void;
}
class Clock implements ClockInterface {
currentTime: Date = new Date();
setTime(d: Date) {
this.currentTime = d;
}
constructor(h: number, m: number) {
// 构造函数逻辑
}
}
接口的高级特性
1. 继承接口
接口可以相互继承:
typescript
interface Shape {
color: string;
}
interface Square extends Shape {
sideLength: number;
}
let square: Square = {
color: "red",
sideLength: 10
};
// 多重继承
interface PenStroke {
penWidth: number;
}
interface Square2 extends Shape, PenStroke {
sideLength: number;
}
let square2: Square2 = {
color: "blue",
penWidth: 5,
sideLength: 20
};
2. 混合类型接口
一个对象可以同时做为函数和对象使用:
typescript
interface Counter {
(start: number): string;
interval: number;
reset(): void;
}
function getCounter(): Counter {
let counter = function (start: number) {
return `Started at ${start}`;
} as Counter;
counter.interval = 123;
counter.reset = function () {
console.log("Counter reset");
};
return counter;
}
let c = getCounter();
c(10);
c.reset();
c.interval = 5.0;
3. 接口合并
TypeScript 会自动合并同名接口:
typescript
interface User {
name: string;
}
interface User {
age: number;
}
// 合并后的 User 接口
let user: User = {
name: "张三",
age: 25
};
实际应用场景
1. API 响应类型定义
typescript
interface ApiResponse<T> {
success: boolean;
data: T;
message?: string;
code: number;
}
interface UserInfo {
id: number;
username: string;
email: string;
avatar?: string;
}
// 使用泛型接口
let userResponse: ApiResponse<UserInfo> = {
success: true,
data: {
id: 1,
username: "zhangsan",
email: "zhangsan@example.com"
},
code: 200
};
2. 组件 Props 类型定义
typescript
interface ButtonProps {
type?: 'primary' | 'secondary' | 'danger';
size?: 'small' | 'medium' | 'large';
disabled?: boolean;
onClick?: (event: MouseEvent) => void;
children: React.ReactNode;
}
const Button: React.FC<ButtonProps> = ({
type = 'primary',
size = 'medium',
disabled = false,
onClick,
children
}) => {
return (
<button
className={`btn btn-${type} btn-${size}`}
disabled={disabled}
onClick={onClick}
>
{children}
</button>
);
};
3. 状态管理类型定义
typescript
interface AppState {
user: UserState;
products: ProductState;
ui: UIState;
}
interface UserState {
currentUser: UserInfo | null;
isLoading: boolean;
error: string | null;
}
interface ProductState {
items: Product[];
selectedProduct: Product | null;
filters: ProductFilters;
}
interface UIState {
theme: 'light' | 'dark';
sidebarOpen: boolean;
notifications: Notification[];
}
最佳实践
1. 命名规范
typescript
// 接口名使用 PascalCase,通常以 I 开头或直接使用描述性名称
interface IUser { } // 传统方式
interface User { } // 推荐方式
// 类型别名使用 PascalCase
type Status = 'pending' | 'approved' | 'rejected';
2. 优先使用接口而不是类型别名
typescript
// 推荐:使用接口
interface User {
id: number;
name: string;
}
// 不推荐:使用类型别名(除非需要联合类型等特殊情况)
type User2 = {
id: number;
name: string;
};
3. 合理使用可选属性
typescript
// 好的实践:明确哪些属性是必需的,哪些是可选的
interface CreateUserRequest {
name: string; // 必需
email: string; // 必需
avatar?: string; // 可选
bio?: string; // 可选
}
4. 使用泛型增强复用性
typescript
interface Repository<T> {
findById(id: number): Promise<T | null>;
findAll(): Promise<T[]>;
create(entity: Omit<T, 'id'>): Promise<T>;
update(id: number, entity: Partial<T>): Promise<T>;
delete(id: number): Promise<void>;
}
// 使用
const userRepository: Repository<User> = new UserRepositoryImpl();
const productRepository: Repository<Product> = new ProductRepositoryImpl();
5. 避免过度使用 any
typescript
// 不好的实践
function processData(data: any): any {
return data.someProperty;
}
// 好的实践
interface InputData {
someProperty: string;
otherProperty?: number;
}
function processData(data: InputData): string {
return data.someProperty;
}
总结
TypeScript 的类型系统和接口是其最强大的特性之一。通过合理使用基础类型和接口,我们可以:
- 提高代码质量:编译时类型检查帮助发现潜在错误
- 增强代码可读性:类型定义即文档,让代码意图更清晰
- 改善开发体验:IDE 智能提示和自动补全
- 便于重构:类型系统帮助安全地重构代码
- 团队协作:统一的类型定义减少沟通成本
掌握这些基础知识后,你就可以更好地利用 TypeScript 的强大功能,编写更安全、更可维护的前端代码。
希望这篇文章对你理解 TypeScript 的基础类型和接口有所帮助。如果大家有任何问题或建议,欢迎在评论区讨论!