TypeScript类型系统本质上是JavaScript的静态类型增强方案,提供三个核心价值:
代码示例:
// 错误示范:未指定类型导致潜在隐患
function add(a, b) {
return a + b;
}
add('hello', 123); // 运行时错误但编译期不报错
// 正确类型标注
function add(a: number, b: number): number {
return a + b;
}
add('hello', 123); // 编译时报错:类型不匹配
// 原生类型
let name: string = 'Alice';
let age: number = 28;
let isStudent: boolean = true;
// 数组类型
let hobbies: string[] = ['reading', 'coding'];
let scores: number[] = [90, 85, 92];
// 元组类型(固定长度的异构数组)
let user: [string, number] = ['Bob', 30];
用于描述对象结构的最常用方式
interface User {
id: number;
name: string;
email?: string; // 可选属性
address: {
city: string;
zipCode: string;
};
}
// 正确实现
const user: User = {
id: 1,
name: 'Charlie',
address: { city: 'Shanghai', zipCode: '200000' }
};
// 错误实现(缺少必要属性)
const invalidUser = { name: 'David' }; // 编译报错
适用于复杂类型抽象
type Point = {
x: number;
y: number;
};
type Rectangle = {
topLeft: Point;
bottomRight: Point;
};
// 更复杂的联合类型
type ResponseData = {
data: T;
error?: string;
};
处理多种可能类型
function processInput(value: string | number) {
if (typeof value === 'string') {
console.log(`String input: ${value}`);
} else {
console.log(`Number input: ${value.toFixed(2)}`);
}
}
processInput('hello'); // 执行字符串分支
processInput(42); // 执行数字分支
processInput(true); // 编译时报错:类型不在联合类型中
合并多个类型特征
interface Serializable {
serialize(): string;
}
class Person {
name: string;
age: number;
}
// 创建同时满足两个条件的类型
type SerializablePerson = Person & Serializable;
class SerializablePersonImpl extends Person implements Serializable {
serialize() {
return JSON.stringify({ name: this.name, age: this.age });
}
}
function getProperty(obj: T, key: K): T[K] {
return obj[key];
}
const user = { name: 'Alice', age: 30 };
const userName = getProperty(user, 'name'); // 推断为string类型
function isNumber(value: any): value is number {
return typeof value === 'number';
}
function printValue(value: any) {
if (isNumber(value)) {
console.log(`Number: ${value}`); // 类型被缩小为number
} else {
console.log(`String: ${value}`); // 类型被缩小为string
}
}
type Readonly = {
readonly [P in keyof T]: T[P];
};
interface User {
name: string;
age: number;
}
type ReadonlyUser = Readonly;
// 所有属性变为只读
{
"compilerOptions": {
"strict": true,
"noImplicitAny": true,
"strictNullChecks": true
}
}
// 不推荐
function handleData(data: any) {
console.log(data.name); // 可能存在运行时错误
}
// 推荐改进
function handleData(data: { name: string }) {
console.log(data.name);
}
// 必要时使用类型断言
const userInput = document.querySelector('#input') as HTMLInputElement;
// 错误示范:返回不确定类型
function fetchUserData(id: number) {
return fetch(`/api/users/${id}`).then(response => response.json());
}
// 正确实现
interface UserResponse {
id: number;
name: string;
email: string;
}
async function fetchUserData(id: number): Promise {
const response = await fetch(`/api/users/${id}`);
if (!response.ok) {
throw new Error('Network error');
}
return response.json() as UserResponse; // 显式断言类型
}
// 不推荐过度嵌套
type DeepReadonly = {
readonly [P in keyof T]-?: DeepReadonly;
};
// 推荐分层抽象
type Readonly = {
readonly [P in keyof T]: T[P];
};
type DeepReadonly = {
readonly [P in keyof T]: DeepReadonly;
};
interface A {
x: number;
}
interface B {
x: string;
}
// 合并会产生联合类型 {x: number} | {x: string}
type C = A & B; // 编译错误:类型不兼容
function process(value: number): number;
function process(value: string): string;
function process(value: any) {
if (typeof value === 'number') return value * 2;
else return value.toUpperCase();
}
// 更好的实现方式
function process(value: T): T extends number ? number : string {
return typeof value === 'number' ? value * 2 : value.toUpperCase();
}
function createArray(length: number, value: T): T[] {
return Array(length).fill(value);
}
const result = createArray(3, 'hello'); // 正确推断为string[]
const numericResult = createArray(3, 5); // 正确推断为number[]
// Partial类型:将所有属性变为可选
type PartialUser = Partial;
// Required类型:将所有属性变为必选
type RequiredUser = Required;
// Omit类型:排除指定属性
type PublicUser = Omit;
// Extract类型:提取共有类型
type CommonProps = Extract;
// Readonly类型:只读属性集合
type ReadonlyUser = Readonly;
// Record类型:键值对映射
type AgeMap = Record;
作为资深开发者,建议建立以下类型安全开发规范:
通过系统性的类型设计,可以显著提升代码的可维护性和健壮性,降低运行时错误率。在实际项目中,建议从核心模块开始逐步引入严格类型检查,配合IDE的类型提示功能,形成良好的类型驱动开发习惯。