TypeScript 基础类型教程
概述
TypeScript 的类型系统是其最强大的特性之一。本教程将深入学习 TypeScript 的各种类型,包括基础类型、对象类型、函数类型等。
基础类型
原始类型
// 字符串
let name: string = "Alice";
let template: string = `Hello, ${name}!`;
// 数字(所有数字都是浮点数)
let age: number = 25;
let pi: number = 3.14159;
let hex: number = 0xf00d;
let binary: number = 0b1010;
let octal: number = 0o744;
// 布尔值
let isActive: boolean = true;
let isComplete: boolean = false;
// BigInt
let bigNumber: bigint = 100n;
let anotherBig: bigint = BigInt(100);
// Symbol
let sym1: symbol = Symbol("key");
let sym2: symbol = Symbol.for("key");
// null 和 undefined
let nothing: null = null;
let notDefined: undefined = undefined;
// void(表示没有返回值)
function log(message: string): void {
console.log(message);
}
// never(表示永不返回)
function error(message: string): never {
throw new Error(message);
}
对象类型
接口定义对象
// 基本接口
interface Person {
name: string;
age: number;
}
// 使用接口
const person: Person = {
name: "Alice",
age: 25
};
// 可选属性
interface User {
id: number;
name: string;
email?: string; // 可选
phone?: string; // 可选
}
const user: User = {
id: 1,
name: "Bob"
// email 和 phone 是可选的
};
// 只读属性
interface Point {
readonly x: number;
readonly y: number;
}
const point: Point = { x: 10, y: 20 };
// point.x = 15; // 错误:只读属性不能修改
类型别名定义对象
// 使用类型别名
type User = {
id: number;
name: string;
email?: string;
};
const newUser: User = {
id: 2,
name: "Charlie"
};
数组类型
基本数组类型
// 类型注解语法
let numbers: number[] = [1, 2, 3, 4, 5];
let strings: string[] = ["a", "b", "c"];
let booleans: boolean[] = [true, false, true];
// 泛型语法
let numbers2: Array<number> = [1, 2, 3, 4, 5];
let strings2: Array<string> = ["a", "b", "c"];
// 只读数组
const readOnlyNumbers: readonly number[] = [1, 2, 3];
// readOnlyNumbers.push(4); // 错误:只读数组不能修改
const readOnlyNumbers2: ReadonlyArray<number> = [1, 2, 3];
元组类型
// 固定长度和类型的数组
let tuple: [string, number] = ["Alice", 25];
// 访问元素
console.log(tuple[0]); // "Alice"
console.log(tuple[1]); // 25
// 可选元素
let optionalTuple: [string, number, boolean?] = ["Bob", 30];
optionalTuple = ["Bob", 30, true];
// 剩余元素
let restTuple: [string, ...number[]] = ["Alice", 1, 2, 3, 4];
函数类型
函数声明
// 函数声明
function add(a: number, b: number): number {
return a + b;
}
// 箭头函数
const multiply = (a: number, b: number): number => {
return a * b;
};
// 函数表达式
const subtract: (a: number, b: number) => number = (a, b) => {
return a - b;
};
函数类型别名
// 定义函数类型
type MathOperation = (a: number, b: number) => number;
// 使用函数类型
const add: MathOperation = (a, b) => a + b;
const multiply: MathOperation = (a, b) => a * b;
// 作为参数
function calculate(operation: MathOperation, a: number, b: number): number {
return operation(a, b);
}
console.log(calculate(add, 5, 3)); // 8
console.log(calculate(multiply, 5, 3)); // 15
可选参数和默认参数
// 可选参数
function greet(name: string, greeting?: string): string {
return greeting ? `${greeting}, ${name}!` : `Hello, ${name}!`;
}
console.log(greet("Alice")); // "Hello, Alice!"
console.log(greet("Bob", "Hi")); // "Hi, Bob!"
// 默认参数
function createName(first: string, last: string = "Smith"): string {
return `${first} ${last}`;
}
console.log(createName("Alice")); // "Alice Smith"
console.log(createName("Bob", "Jones")); // "Bob Jones"
剩余参数
// 剩余参数
function sum(...numbers: number[]): number {
return numbers.reduce((total, num) => total + num, 0);
}
console.log(sum(1, 2, 3)); // 6
console.log(sum(1, 2, 3, 4, 5)); // 15
函数重载
// 函数重载
function add(a: number, b: number): number;
function add(a: string, b: string): string;
function add(a: any, b: any): any {
return a + b;
}
console.log(add(1, 2)); // 3
console.log(add("Hello", "World")); // "HelloWorld"
联合类型和交叉类型
联合类型
// 联合类型
type ID = string | number;
function printId(id: ID) {
console.log(`ID: ${id}`);
}
printId(101); // "ID: 101"
printId("abc-123"); // "ID: abc-123"
// 更复杂的联合类型
type Success = {
status: "success";
data: any;
};
type Error = {
status: "error";
message: string;
};
type Result = Success | Error;
function handleResult(result: Result) {
if (result.status === "success") {
console.log("Data:", result.data);
} else {
console.log("Error:", result.message);
}
}
交叉类型
// 交叉类型
type Person = {
name: string;
age: number;
};
type Employee = {
employeeId: number;
department: string;
};
type EmployeePerson = Person & Employee;
const employee: EmployeePerson = {
name: "Alice",
age: 25,
employeeId: 1001,
department: "Engineering"
};
字面量类型
字符串字面量
// 字符串字面量类型
type Direction = "up" | "down" | "left" | "right";
function move(direction: Direction) {
console.log(`Moving ${direction}`);
}
move("up"); // 正确
// move("diagonal"); // 错误
// 模板字符串字面量
type EventName<T extends string> = `on${Capitalize<T>}`;
// 登录事件
type LoginEvent = EventName<"login">; // "onLogin"
type LogoutEvent = EventName<"logout">; // "onLogout"
数字字面量
// 数字字面量类型
type DiceRoll = 1 | 2 | 3 | 4 | 5 | 6;
function rollDice(): DiceRoll {
return Math.floor(Math.random() * 6) + 1 as DiceRoll;
}
// 误差数字
type ApproximateNumber = number | `${number}.${number}`;
布尔字面量
// 布尔字面量类型
type Success = true;
type Failure = false;
function checkResult(result: Success | Failure) {
if (result) {
console.log("操作成功");
} else {
console.log("操作失败");
}
}
类型推断
基础类型推断
// 自动推断类型
let x = 3; // number
let y = "hello"; // string
let z = true; // boolean
// 最佳通用类型
let arr = [0, 1, null]; // (number | null)[]
上下文类型
// 上下文类型推断
window.onmousedown = function(mouseEvent) {
console.log(mouseEvent.button); // 自动推断为 MouseEvent
};
// 函数参数
function createMap(pairs: [string, number][]) {
const map: Record<string, number> = {};
for (const [key, value] of pairs) {
map[key] = value; // 自动推断 value 为 number
}
return map;
}
类型守卫
typeof 类型守卫
// typeof 类型守卫
function printLength(value: string | number) {
if (typeof value === "string") {
console.log(value.length);
} else {
console.log(value.toFixed(2));
}
}
printLength("hello"); // 5
printLength(3.14159); // "3.14"
instanceof 类型守卫
// instanceof 类型守卫
function logValue(value: Date | string[]) {
if (value instanceof Date) {
console.log(value.toISOString());
} else {
console.log(value.join(", "));
}
}
logValue(new Date());
logValue(["a", "b", "c"]);
自定义类型守卫
// 自定义类型守卫
interface Fish {
swim(): void;
}
interface Bird {
fly(): void;
}
function isFish(pet: Fish | Bird): pet is Fish {
return (pet as Fish).swim !== undefined;
}
function movePet(pet: Fish | Bird) {
if (isFish(pet)) {
pet.swim();
} else {
pet.fly();
}
}
类型断言
类型断言语法
// 尖括号语法
let value: any = "hello world";
let strLength: number = (<string>value).length;
// as 语法(推荐)
let strLength2: number = (value as string).length;
// 非空断言
function getEmail(email: string | null | undefined): string {
return email!;
}
const 断言
// const 断言
const config = {
endpoint: "https://api.example.com",
timeout: 5000
} as const;
// 推断为具体字面量类型
type Config = typeof config;
// type Config = {
// readonly endpoint: "https://api.example.com";
// readonly timeout: 5000;
// }
映射类型
基础映射类型
// 将所有属性变为可选
type Partial<T> = {
[P in keyof T]?: T[P];
};
interface User {
id: number;
name: string;
email: string;
}
type PartialUser = Partial<User>;
// {
// id?: number;
// name?: string;
// email?: string;
// }
// 将所有属性变为必需
type Required<T> = {
[P in keyof T]-?: T[P];
};
// 将所有属性变为只读
type Readonly<T> = {
readonly [P in keyof T]: T[P];
};
条件类型
// 条件类型
type NonNullable<T> = T extends null | undefined ? never : T;
type Result1 = NonNullable<string | null>; // string
type Result2 = NonNullable<number | undefined>; // number
// 提取类型
type Flatten<T> = T extends any[] ? T[number] : T;
type Flat1 = Flatten<string[]>; // string
type Flat2 = Flatten<number>; // number
总结
本教程详细介绍了 TypeScript 的类型系统:
-
基础类型:
- 原始类型:string、number、boolean、bigint、symbol
- 特殊类型:null、undefined、void、never
-
对象类型:
- 接口定义对象结构
- 可选属性和只读属性
- 类型别名
-
数组类型:
- 基本数组类型
- 只读数组
- 元组类型
-
函数类型:
- 函数声明和表达式
- 函数类型别名
- 可选参数、默认参数、剩余参数
- 函数重载
-
联合类型和交叉类型:
- 联合类型:值的并集
- 交叉类型:类型的交集
-
字面量类型:
- 字符串字面量
- 数字字面量
- 布尔字面量
-
类型推断:
- 基础类型推断
- 上下文类型推断
-
类型守卫:
- typeof 类型守卫
- instanceof 类型守卫
- 自定义类型守卫
-
类型断言:
- 类型断言语法
- 非空断言
- const 断言
-
映射类型:
- 基础映射类型
- 条件类型
TypeScript 的类型系统非常强大,掌握这些类型知识将帮助你编写更安全、更可维护的代码。
下一步
在下一教程中,我们将深入学习 TypeScript 的接口和高级类型,包括:
-
接口的高级特性
-
类
-
抽象类
-
访问修饰符
-
继承和多态
继续学习 TypeScript,掌握这门强大语言的更多特性!

