1. 滥用 any
类型
坏习惯:用 any
逃避类型检查,导致类型安全性丧失。
改进:
- 使用更精确的类型(如联合类型、泛型)。
- 无法确定类型时,优先用
unknown
+ 类型断言。
typescript
复制
// ❌ Bad
function parse(data: any) { /*...*/ }
// ✅ Good
function parse<T>(data: T): ParsedResult<T> { /*...*/ }
2. 忽略 strict
模式
坏习惯:关闭 strict
模式(strictNullChecks
、strictFunctionTypes
等)。
改进:
- 始终开启
strict
,强制代码健壮性。 - 处理可能的
undefined
/null
:
typescript
复制
// ❌ Bad
const name = user.name; // 可能报错
// ✅ Good
const name = user?.name ?? 'default';
**3. 不区分 interface
和 type
**
坏习惯:混用 interface
和 type
,缺乏一致性。
改进:
-
interface
:用于对象形状(可扩展,适合公共 API)。 -
type
:用于联合类型、元组等复杂类型。
typescript
复制
// ❌ Bad
type User = { name: string }; // 简单对象用 interface 更合适
// ✅ Good
interface User { name: string }
type UserID = string | number;
4. 不写返回值类型
坏习惯:依赖类型推断,函数返回值不明确。
改进:显式声明返回值类型,便于维护和文档化。
typescript
复制
// ❌ Bad
function add(a: number, b: number) { return a + b; }
// ✅ Good
function add(a: number, b: number): number { return a + b; }
5. 过度使用非空断言(!
)
坏习惯:用 !
强制忽略 null/undefined
,掩盖潜在问题。
改进:用可选链(?.
)或条件判断处理。
typescript
复制
// ❌ Bad
const name = user!.name;
// ✅ Good
const name = user?.name ?? 'unknown';
6. 不处理 Promise
错误
坏习惯:忽略 catch
,导致未捕获的异常。
改进:始终处理 Promise
错误。
typescript
复制
// ❌ Bad
fetchData().then(data => console.log(data));
// ✅ Good
fetchData()
.then(data => console.log(data))
.catch(err => console.error('Failed:', err));
7. 硬编码魔术字符串/数字
坏习惯:直接使用字符串/数字,难以维护。
改进:用枚举或常量替代。
typescript
复制
// ❌ Bad
if (status === 'active') { /*...*/ }
// ✅ Good
enum Status { Active = 'active', Inactive = 'inactive' }
if (status === Status.Active) { /*...*/ }
**8. 忽略 readonly
和 const
**
坏习惯:允许意外修改数据。
改进:用 readonly
或 const
保护不可变数据。
typescript
复制
// ❌ Bad
let config = { apiUrl: 'https://api.com' };
config.apiUrl = 'hacked!';
// ✅ Good
const config = { apiUrl: 'https://api.com' } as const;
9. 不校验外部数据
坏习惯:假设 API 返回的数据符合预期。
改进:使用类型守卫或库(如 zod
)校验运行时数据。
typescript
复制
// ❌ Bad
const user: User = await fetchUser();
// ✅ Good
const user = UserSchema.parse(await fetchUser()); // zod 校验
**10. 滥用 @ts-ignore
**
坏习惯:用注释掩盖问题,而非修复类型错误。
改进:优先解决类型问题,或使用更安全的 @ts-expect-error
。
typescript
复制
// ❌ Bad
// @ts-ignore
const name = user.nmae; // 拼写错误被忽略
// ✅ Good
// @ts-expect-error - 明确说明此处需要忽略
const name = user.nmae;
11. 不利用泛型
坏习惯:重复定义相似函数。
改进:用泛型抽象通用逻辑。
typescript
复制
// ❌ Bad
function getString(value: string): string { return value; }
function getNumber(value: number): number { return value; }
// ✅ Good
function getValue<T>(value: T): T { return value; }
**12. 忽略 keyof
和 typeof
**
坏习惯:手动维护类型与值的同步。
改进:用 keyof
/typeof
动态生成类型。
typescript
复制
// ❌ Bad
interface Config { apiUrl: string; timeout: number; }
const config = { apiUrl: '...', timeout: 5000 }; // 重复定义
// ✅ Good
const config = { apiUrl: '...', timeout: 5000 } as const;
type Config = typeof config;
13. 不分离类型和逻辑
坏习惯:类型定义与业务代码混杂。
改进:将类型抽离到单独文件(如 types.ts
)。
typescript
复制
// ❌ Bad
function getUser(): { name: string; age: number } { /*...*/ }
// ✅ Good
// types/user.ts
interface User { name: string; age: number; }
// services/user.ts
function getUser(): User { /*...*/ }
14. 不利用工具类型
坏习惯:手写复杂类型。
改进:使用内置工具类型(Partial
、Pick
、Omit
等)。
typescript
复制
// ❌ Bad
interface User { name: string; age: number; }
interface OptionalUser { name?: string; age?: number; }
// ✅ Good
type OptionalUser = Partial<User>;
15. 忽略 never
类型
坏习惯:未穷举所有条件分支。
改进:用 never
检测未处理的情况。
typescript
复制
// ❌ Bad
function handleStatus(status: string) {
if (status === 'success') { /*...*/ }
// 漏掉了其他状态
}
// ✅ Good
function handleStatus(status: 'success' | 'error') {
switch (status) {
case 'success': /*...*/ break;
default: const _exhaustiveCheck: never = status; // 编译时报错
}
}
16. 不写 JSDoc 或类型注释
坏习惯:代码缺乏文档,难以理解。
改进:用 JSDoc 或 TSDoc 描述复杂逻辑。
typescript
复制
// ❌ Bad
function calculate(a, b) { return a + b; }
// ✅ Good
/**
* 计算两个数字的和
* @param a - 第一个加数
* @param b - 第二个加数
* @returns 两数之和
*/
function calculate(a: number, b: number): number { return a + b; }
总结
TypeScript 的核心价值在于 类型安全 和 可维护性。改掉这些坏习惯后,你的代码将:
- 更少运行时错误
- 更易重构和扩展
- 更清晰的协作接口
行动建议:
- 定期用
tsc --noEmit
检查类型错误。 - 使用 ESLint 规则(如
@typescript-eslint/no-explicit-any
)强制最佳实践。
希望这篇文章能帮助你写出更专业的 TypeScript 代码!