TypeScript 实用技巧分享
类型推断的妙用
TypeScript 的类型推断非常强大,善用它可以减少冗余代码:
// 不需要显式声明类型
const numbers = [1, 2, 3]; // number[]
const user = { name: 'John', age: 30 }; // { name: string; age: number }
实用工具类型
Partial 和 Required
interface User {
name: string;
email: string;
age?: number;
}
// 所有属性变为可选
type PartialUser = Partial<User>;
// 所有属性变为必需
type RequiredUser = Required<User>;
Pick 和 Omit
// 只选择部分属性
type UserBasic = Pick<User, 'name' | 'email'>;
// 排除某些属性
type UserWithoutAge = Omit<User, 'age'>;
类型守卫
function isString(value: unknown): value is string {
return typeof value === 'string';
}
function process(value: unknown) {
if (isString(value)) {
// 这里 value 被推断为 string
console.log(value.toUpperCase());
}
}
泛型约束
interface HasLength {
length: number;
}
function logLength<T extends HasLength>(item: T): void {
console.log(item.length);
}
logLength('hello'); // OK
logLength([1, 2, 3]); // OK
logLength({ length: 10 }); // OK
satisfies 操作符
TypeScript 4.9 引入的 satisfies 操作符,让你在保留精确类型推断的同时验证类型约束:
type Colors = 'red' | 'green' | 'blue';
type RGB = [number, number, number];
// 使用类型注解:丢失了具体的字面量类型
const palette1: Record<Colors, string | RGB> = {
red: [255, 0, 0],
green: '#00ff00',
blue: [0, 0, 255],
};
palette1.red.map(x => x); // ❌ 报错:string | RGB 没有 map 方法
// 使用 satisfies:保留精确类型,同时验证结构
const palette2 = {
red: [255, 0, 0],
green: '#00ff00',
blue: [0, 0, 255],
} satisfies Record<Colors, string | RGB>;
palette2.red.map(x => x); // ✅ OK,red 被推断为 [number, number, number]
palette2.green.toUpperCase(); // ✅ OK,green 被推断为 string
常见用途
// 1. 配置对象验证
interface Config {
apiUrl: string;
timeout: number;
retries?: number;
}
const config = {
apiUrl: 'https://api.example.com',
timeout: 5000,
retries: 3,
} satisfies Config;
// 2. 确保对象键的完整性
type Routes = 'home' | 'about' | 'contact';
const routes = {
home: '/',
about: '/about',
contact: '/contact',
} satisfies Record<Routes, string>;
// 如果漏掉任何一个路由,TypeScript 会报错
掌握这些技巧,能让你的 TypeScript 代码更加优雅和类型安全。
评论