注册
web

2024:写 TypeScript 必须改掉的 10 个坏习惯

大家好,我是CodeQi! 一位热衷于技术分享的码仔。


在过去的几年里,TypeScript 已经逐渐成为了前端开发的首选语言,尤其是那些追求更高代码质量和类型安全的开发者。不过,正如所有编程语言一样,随着时间的推移和技术的进步,我们的编程习惯也应该与时俱进。


👋 你有没有想过,自己在写 TypeScript 时是否养成了一些“坏习惯”?


随着 TypeScript 生态系统的进一步成熟,有些你以前觉得合理的做法,现在可能不太合理。接下来,我将分享10 个常见的 TypeScript 坏习惯,并告诉你如何改进它们,确保你的代码更健壮、性能更高、并且更加易于维护。


1. 不使用 strict 模式


当开发者为了减少“麻烦”而禁用 TypeScript 的 strict 模式时,往往是在给自己埋雷。💣


为什么不好?


strict 模式通过强制进行更严格的类型检查,帮助我们避免潜在的错误。如果你关掉它,TypeScript 就变得更像是 JavaScript,失去了静态类型带来的种种好处。短期内你可能会觉得更自由,但未来的重构和维护将变得更加棘手。


怎么改进?


在 tsconfig.json 中启用 strict 模式,这样你的代码在未来的迭代中会更加稳健:


{
  "compilerOptions": {
    "strict": true
  }
}

2. 依赖 any 类型


any 可能是 TypeScript 中最具“争议”的类型之一,因为它违背了我们使用 TypeScript 的初衷:类型安全


为什么不好?


any 让 TypeScript 失去意义。它让代码回归到“JavaScript 模式”,绕过了类型检查,最终可能导致各种运行时错误。


怎么改进?


使用 unknown 替代 any,并在实际使用前对类型进行检查。unknown 更安全,因为它不会自动允许任何操作:


let dataunknown;

if (typeof data === "string") {
  console.log(data.toUpperCase());
}

3. 过度使用类型断言


你是否经常用 as 关键字来“消除”编译错误?🙈 这种做法短期内看似有效,但可能会隐藏更多问题。


为什么不好?


类型断言会绕过 TypeScript 的安全机制,告诉编译器“别管了,我知道自己在做什么”。问题是,当你其实并不完全确定时,它会导致难以追踪的运行时错误。


怎么改进?


减少类型断言,使用类型保护函数代替:


function isString(value: unknown): value is string {
  return typeof value === 'string';
}

if (isString(data)) {
  console.log(data.toUpperCase());
}

4. 忽视联合类型和交叉类型


联合类型 (|) 和交叉类型 (&) 是 TypeScript 中极其强大的工具,但它们经常被忽视。🚫


为什么不好?


没有联合和交叉类型,代码容易变得冗长而难以维护。你可能会写大量的冗余代码,而这些类型可以帮你更简洁地表达逻辑。


怎么改进?


使用联合类型来处理不同情况,交叉类型来组合多个类型:


type Admin = { isAdmintrueprivilegesstring[] };
type User = { isAdminfalseemailstring };

type Person = Admin | User;

function logUser(person: Person) {
  if (person.isAdmin) {
    console.log(person.privileges);
  } else {
    console.log(person.email);
  }
}

5. 使用非特定的返回类型


不为函数指定精确的返回类型,可能会让使用者摸不着头脑。🤔


为什么不好?


模糊的返回类型增加了代码的不确定性,调试难度也会增加。你失去了静态类型的优势,最终使代码变得不可靠。


怎么改进?


始终为函数指定明确的返回类型,哪怕它是一个联合类型:


function fetchData(): Promise<{ idnumbernamestring }> {
  return fetch("/data").then(response => response.json());
}

6. 忽视 null 和 undefined


一些开发者在处理 null 和 undefined 时掉以轻心,结果导致一堆潜在的运行时错误。


为什么不好?


JavaScript 允许变量为 null 或 undefined,TypeScript 也有相应的工具帮助处理这些值。如果忽视它们,代码可能会在运行时崩溃。


怎么改进?


使用可选链 (?.) 和空值合并操作符 (??) 处理 null 和 undefined


const name = user?.profile?.name ?? "Guest";

7. 过度使用 Enums


在 TypeScript 中,Enums 有时会被滥用。尽管它们有其应用场景,但并不总是必要。


为什么不好?


Enums 会增加复杂性,尤其是在简单常量足够的情况下。


怎么改进?


考虑用 const 或字面量类型来替代枚举:


type Role = "Admin" | "User" | "Guest";

let userRoleRole = "Admin";

8. 不使用 readonly


如果不使用 readonly 来防止对象或数组的意外修改,代码中的副作用将难以控制。


为什么不好?


可变性会导致对象在不经意间被修改,造成难以调试的问题。


怎么改进?


尽可能使用 readonly 来确保不变性:


const datareadonly number[] = [123];

9. 忽视自定义类型保护


依赖隐式类型检查而非明确的类型保护,可能导致你错过一些重要的类型问题。


为什么不好?


没有自定义类型保护,你可能会在运行时错过一些类型错误,最终导致不可预期的行为。


怎么改进?


编写明确的类型保护函数:


function isUser(user: any): user is User {
  return typeof user.email === "string";
}

10. 没有充分利用 unknown 类型


许多开发者默认使用 any 来处理未知类型,其实 unknown 是一个更好的选择。


为什么不好?


any 禁用了类型检查,而这正是使用 TypeScript 的初衷。unknown 则要求你在使用前对类型进行明确的验证。


怎么改进?


用 unknown 代替 any,并在使用前进行类型缩小:


let inputunknown;

if (typeof input === "string") {
  console.log(input.toUpperCase());
}

总结


2024 年,是时候告别这些坏习惯了!通过启用 strict 模式、避免使用 any、掌握联合和交叉类型等高级特性,你的 TypeScript 代码将变得更强大、更灵活、更具维护性。希望这些建议能够帮助你在 TypeScript 之路上走得更远,写出更加优雅的代码!✨


作者:CodeQi技术小栈
来源:juejin.cn/post/7426298029286916146

0 个评论

要回复文章请先登录注册