最近升级了5.8,碰到了一个问题: 启用 “erasableSyntaxOnly” 时,不允许使用此语法。ts(1294)
遂收集了一些erasableSyntaxOnly的资料分享一下
参考:
www.totaltypescript.com/erasable-sy…
什么是 erasableSyntaxOnly?
erasableSyntaxOnly 是一个编译器标志,它的主要目的是确保我们只使用那些在编译后不会生成额外 JavaScript 代码的 TypeScript 特性。简单来说,它要求我们只使用"可擦除"的语法。
哪些特性会被禁用?
这个标志会禁用以下特性:
- 枚举(Enums)
// 报错!启用 “erasableSyntaxOnly” 时,不允许使用此语法。ts(1294)
enum Status {
Success = "Success",
Error = "Error"
}
- 命名空间(Namespaces)
// 报错!启用 “erasableSyntaxOnly” 时,不允许使用此语法。ts(1294)
namespace Utils {
export const version = "1.0.0";
}
- 类中的参数属性
// 报错!启用 “erasableSyntaxOnly” 时,不允许使用此语法。ts(1294)
class User {
constructor(private name: string) {}
}
为什么需要这个标志?
1. 运行时性能考虑
这些特性在编译后会生成额外的 JavaScript 代码,增加了代码体积。以枚举为例,它会被编译成一个双向映射的对象,这在运行时会产生不必要的开销。
2. 与 Node.js 的 TypeScript 支持相关
Node.js 最近添加了对 TypeScript 的原生支持,但它只支持"可擦除"的语法。这意味着如果你想要在 Node.js 中直接运行 TypeScript 文件,就需要避免使用这些会生成额外代码的特性。
3. 未来 JavaScript 类型系统的发展
目前有多个提案正在讨论将类型系统引入JavaScript,比如"types as comments"提案。这些提案都只支持"可擦除"的语法,因为浏览器需要能够直接忽略类型信息。
实际开发中的影响
替代方案
- 枚举的替代方案:
// 替代枚举
const Status = {
Success: "Success",
Error: "Error"
} as const;
type StatusType = typeof Status[keyof typeof Status];
- 命名空间的替代:
// 使用模块替代命名空间
export const Utils = {
version: "1.0.0"
};
导入路径别名的处理
erasableSyntaxOnly也会影响tsconfig.json中的paths配置。建议使用package.json中的imports字段来处理导入路径别名,这是Node.js原生支持的方式。
个人建议
- 在新项目中考虑启用
erasableSyntaxOnly,这样可以确保代码更加轻量和可维护。 - 现有项目不要急于迁移,可以逐步减少对这些特性的使用。
- 在编写库或框架时,特别要注意避免使用这些特性,因为它们可能会影响最终打包的大小和性能。
- 关注
TypeScript和JavaScript类型系统的发展,为未来的变化做好准备。
总结
erasableSyntaxOnly会改变我们的开发习惯,但是它的引入也反映了TypeScript团队对代码质量和性能的重视。
从长远来看,有助于我们写出更加高效和可维护的代码。