如果你和我一样,你可能会因为被迫而使用 Typescript。你的公司决定它会成为未来的语言,所以你被迫学习它。起初,您很高兴使用 Typescript。你知道它有很大的潜力,可以帮助你制作更强大的应用程序。但在使用了一段时间后,您开始意识到它是多么烦人和令人沮丧。
在这篇文章中,我将发泄我对 Typescript 的不满。我刚开始使用它,大约一个月了,并且正在努力掌握它。使用一段时间后,我发现它太糟糕了,而且有些地方我根本不喜欢它。
但在克服它的缺点之前,让我们先对该语言进行一个温和的高度概述。
👉目录(TOC)。
什么是打字稿?
为什么我们有 TypeScript?
我应该使用它吗?
打字稿的问题。
1. 学习曲线。
2. 严格的类型检查系统。
3.冗长且缺乏可读性。
4.缺乏直观的语法。
5.缺乏兼容性。
6. 低生产率。
7. 虚假承诺。
8. 缺乏灵活性。
9. 滥用巨人公司。
10. 聪明的开发者滥用。
11. 不是 JS 超集。
12. 较慢的编译时间。
13. 额外的转译步骤。
14. 缺乏表现。
15. 编写单元测试。
16. 类型没那么有用。
17. 更重的技术债务。
TypeScript 替代品。
1. JSDoc。
2.流动。
你应该选择哪一个?
Javascript 的下一步是什么?
结论。
什么是打字稿?
打字稿徽标。
TypeScript 由 Microsoft 开发和维护,也称为可扩展的 JavaScript,是一种面向对象的开源编程语言。它可以说是 JavaScript 的超集,恐怕我不同意,它包含额外的类型。这是一个简单的代码片段,演示了 JavaScript 和 TypeScript 之间的区别:
// JavaScriptvarname="World!"console.log(`Hello, ${name}`)// TypeScriptvarname:string="World!"// Or simply// var name = "World!"console.log(`Hello, ${name}`)
你猜对了。完全没有区别。因此,TypeScript 是一种静态而非强编译的编程语言,用于编写清晰简洁的 JavaScript 代码。它实现与 JavaScript 相同的目的,可用于客户端和服务器端应用程序。此外,用 JavaScript 编写的代码库也与 TypeScript 兼容,这是一件好事。
然而,Typescript 承诺通过其类型系统使 Web 开发比以往任何时候都更容易和更安全。不幸的是,它没有兑现承诺。Typescript 是一种难以学习的语言,并且通常伴随着烦人的学习曲线。即使是经验丰富的开发人员也会发现自己在使用这种语言 [ 0]时苦苦挣扎。
为什么我们有 TypeScript?
图片由Gordon Johnson在Pixabay上发布。
🔝前往目录。
您可能会想,“我为什么要这样做?我可以改用 JavaScript。” 原因是,通过键入变量,您可以在编译时而不是运行时捕获错误。例如,如果您尝试添加一个字符串和一个数字并将结果存储为数字,您将收到类型错误:
varx:number=1;vary:string="2";varz:number=x+y;// output: Type 'string' is not assignable to type 'number'.ts(2322)
但是,如果您在 JavaScript 中尝试此操作,代码将运行而不会出现任何错误:
varx=1;vary="2";varz=x+y;// output: 12
如您所见,类型可以帮助您在开发过程的早期发现错误。通过添加可选的静态类型,TypeScript 使我们能够更明确地了解他们正在编写的代码并快速识别潜在问题。这使团队更容易协作并减少调试代码所花费的时间。
但是,仍然存在一些不足的情况。例如,请考虑以下示例:
functionpush(arr:Array<string|number>){arr.push(99);}letfoo:Array<string>=['foo'];push(foo);
即使我们将数字压入字符串数组,TypeScript 也无法识别类型不匹配并成功地对代码进行了类型检查。这是有问题的,因为类型不匹配不是很明显,这会导致运行时错误。
尽管我对面向对象编程有所保留,但对于需要强对象类型的 OOP 爱好者来说,TypeScript 可能是一个非常有用的工具。使用 TypeScript 编译器,我们可以生成具有面向对象编程的所有特性和优点的代码。虽然 JavaScript 不支持强类型的面向对象编程原则,但 TypeScript 支持。
但这并不意味着您应该为所有项目考虑使用 TypeScript。正如他们的文档中所述,像 Microsoft [ 1]这样规模的公司并不多。如果您正在处理大型 JavaScript 项目,TypeScript 可能是一个不错的选择。但是,如果您刚开始编程或从事一个小项目,那么最好还是坚持使用通常的普通好旧 JavaScript。
我应该使用它吗?
图片由Dave M从Pixabay 提供。
🔝前往目录。
现在的问题是:你应该在下一个项目中使用 TypeScript 吗?答案在于它的特点。正如我之前所说,TypeScript 提供了可选的静态类型、类和接口,可以帮助您更有效地开发大型应用程序。
我认为在有多个开发人员的大中型项目中使用 TypeScript 可能会更好,但有时情况并非如此。使用 TypeScript 的好处包括:
静态类型:这是一个非常简单的类型。这意味着您甚至可以在代码运行之前在编译时捕获错误。这使代码更可预测且更易于调试。但是,正如我们之前所见,情况并非总是如此
类型推断:TypeScript 通常可以推断变量的类型,这意味着您不必显式声明它们。这可以使您的代码更简洁,更易于阅读。然而,这也可以通过 JavaScript 和 JSDoc 来实现。
IntelliSense:这是 Visual Studio Code 的一项功能,可根据变量类型提供自动完成建议。这可以再次使您的代码更易于编写并且不易出错。然而,IntelliSense 并未与 TypeScript 紧密耦合,但也受 JavaScript [ 2]支持。
简而言之,我们有一个更具体、文档更好、更可靠、质量更高的代码。然而,在使用它一段时间后,您可能会发现它降低了代码的可读性,这是我们将在下一节中讨论的许多问题之一。因此,在使用 TypeScript 之前,您应该仔细考虑它是否适合您的项目。
打字稿的问题。
State of JS最不喜欢的 TypeScript 方面。
在接下来的部分中,我们将探索我开始比以往更多地放弃 Typescript 的事情列表。虽然 Typescript 是一个强大的工具,但它也有一些主要的缺点,这让我更频繁地回到 JavaScript。
1. 学习曲线。
陡峭的学习曲线(作者图片)。
🔝前往目录。
Typescript 学习起来既困难又费时。您必须精通 JavaScript 和类型系统才能有效地使用 Typescript。这意味着您必须花时间了解类型系统的复杂性以及您如何与 JavaScript 代码交互。即使是经验丰富的开发人员也会发现这一点难以掌握,这使得它成为任何新开发项目的巨大进入障碍。
此外,Typescript 有一些难以解决的特性。对于经验丰富的开发人员来说,不可否认的是,学习 Typescript 可能是一个耗时的过程。团队必须大力投资于培训,以确保每个人都了解最新的变化和最佳实践。在理解使用 Typescript 作为其主要语言的现有代码库时,这也会带来挑战。
简而言之,与 Typescript 相关的学习曲线可能非常陡峭,需要花费大量时间和精力才能掌握。
2. 严格的类型检查系统。
🔝前往目录。
另一个问题是 Typescript 的类型检查系统通常过于严格且难以使用。在处理不完全适合类型系统的复杂类型或功能时,这种严格的方法可能会导致额外的工作和调试时间。随着时间的推移,这种额外的工作量会迅速增加,最终会减慢开发周期。
以下使用算术实用程序类型的纯类型冒泡排序示例过于严格且难以使用 [ 3]。尽管比较器类型很聪明,但它抽象掉了一些条件,使其难以调试和维护。这种类型的代码对于初学者来说特别难掌握,因为它需要对类型及其行为有深刻的理解。
typeTest1=BubbleSort<[1,4,1,3,2]>// ^?typeTest2=BubbleSort<[4,2,1,8,5]>// ^?typeTest3=BubbleSort<[-1,-9,999,50]>// ^? ----------------BUBBLE SORT----------------typeBubbleSort<Nextendsnumber[]>=BubbleSortPass<N>extendsIs<inferOnePass,number[]>?BubbleSortPass<OnePass>extendsBubbleSortPass<N>?BubbleSortPass<N>:BubbleSort<OnePass>:nevertypeBubbleSortPass<Nextendsnumber[]>=Nextends[Is<inferFirst,number>,Is<inferSecond,number>,...inferRest]?Restextendsnumber[]?Restextends[]?LessThan<First,Second>extendstrue?[First,Second]:[Second,First]:LessThan<First,Second>extendstrue?[First,...BubbleSortPass<[Second,...Rest]>]:[Second,...BubbleSortPass<[First,...Rest]>]:never:never ---------------UTILITY TYPES---------------typeLessThan<Aextendsnumber,Bextendsnumber>=IsPositive<A>extendstrue?IsPositive<B>extendstrue?Aextends0?Bextends0?false:true:Bextends0?false:LessThan<Subtract<A,1>,Subtract<B,1>>:false:IsPositive<B>extendstrue?true:`${A}`extends`-${inferPosAStr}`?`${B}`extends`-${inferPosBStr}`?StringToNumber<PosAStr>extendsIs<inferPositiveA,number>?StringToNumber<PosBStr>extendsIs<inferPositiveB,number>?LessThan<PositiveB,PositiveA>:never:never:never:nevertypeIs<TextendsU,U>=T;typeAdd<Aextendsnumber,Bextendsnumber>=StrictTupleLength<[...TupleOfLength<0,A>,...TupleOfLength<0,B>]>;typeSubtract<Aextendsnumber,Bextendsnumber>=TupleOfLength<0,A>extends[...TupleOfLength<0,B>,...inferResult]?Result['length']:never;typeIsPositive<Nextendsnumber>=`${N}`extends`-${number}`?false:true;// https://stackoverflow.com/a/70526775/16121252typeStringToNumber<Textendsstring,Aextendsany[]=[]>=Textendskeyof[0,...A]?A['length']:StringToNumber<T,[0,...A]>/// Types the utilities rely ontypeStrictTupleLength<T>=Textends{length:Is<inferL,number>}?L:nevertypeTupleOfLength<T,Lextendsnumber,RextendsT[]=[],>=R['length']extendsL?R:TupleOfLength<T,L,[...R,T]>;
3.冗长且缺乏可读性。
🔝前往目录。
当我开始使用 Typescript 的旅程时,我首先注意到这种语言是多么冗长。与 JavaScript 相比,它需要大量额外的输入。这可以归因于严格的语法和必须记住的众多规则。对于那些习惯于用其他语言快速高效地编写代码的人来说,这可能会非常令人沮丧。
在尝试学习语言和调试代码时,Typescript 的冗长可能是一个很大的障碍。这是因为跟踪代码中的所有不同元素可能很困难。
本应为代码库带来可读性和清晰度的语言反而掩盖了它。下面的代码是文档化的 TypeScript 示例,它非常臃肿。这使得代码难以阅读和理解,这是反对使用 TypeScript 的主要论据之一。
classRectangle{width:number|stringlength:number|string/**
* Create a Rectangle instance.
*
* @param {number} width - The width of the rectangle.
* @param {number} [length] - The length of the rectangle.
*/constructor(width:number|string,length:number|string=20){this.width=widththis.length=length}/**
* Calculate the area of a rectangle.
*
* @returns {number} - The area of a rectangle.
*
* @example Correct usage.
*
* // Returns 200
* calcArea(10, 20);
*
*/calcArea():number{varwidth=Number(this.width)varlength=Number(this.length)returnwidth*length}}
您必须在代码中添加如此多的类型注释。说真的,只使用 JavaScript。它更快、更简单,而且您不必担心通过 JSDoc 呈现的所有此类内容。
classRectangle{widthlength/**
* Create a Rectangle instance.
*
* @param {number} width - The width of the rectangle.
* @param {number} [length] - The length of the rectangle.
*/constructor(width,length=20){this.width=widththis.length=length}/**
* Calculate the area of a rectangle.
*
* @returns {number} - The area of a rectangle.
*
* @example Correct usage.
*
* // Returns 200
* calcArea(10, 20);
*
*/calcArea(){varwidth=Number(this.width)varlength=Number(this.length)returnwidth*length}}
图片由作者提供。
这个例子告诉你为什么你不应该使用 TypeScript。如果您考虑查看官方核心 TypeScript 代码库,您会注意到整个代码库中使用了过多不必要的类型注释。这表明您应该尽可能避免使用 TypeScript,而是坚持使用带有 JSDoc 的 Javascript。
4.缺乏直观的语法。
🔝前往目录。
Typescript 语法可能难以理解,尤其是对于那些刚接触编程的人来说。该语言使用来自其他语言的开发人员不熟悉的约定,并且可能使阅读和理解代码变得困难。
即使您熟悉了该语言的语法,对于初学者来说,错误仍然难以辨认。这是因为 Typescript 有非常严格的规则和约定,所以即使某些东西看起来有效,也可能不会被编译器接受。例如,Typescript 要求用类型声明变量,并且函数中的每个参数都必须分配一个类型。如果不满足这些要求,您将收到一条错误消息,这可能会让编程新手感到困惑。
作为初学者克服这些障碍的唯一方法是耐心并坚持下去。不要误会我的意思。Typescript 仍然是一种强大的语言,可以让你编写更干净、更高效的代码,但需要时间来适应语法和约定。
5.缺乏兼容性。
🔝前往目录。
TypeScript 似乎是一个很棒的工具,但它并不总是能与其他工具很好地协同工作。例如,我最近为 NodeJs 环境编写了一个 Lambda 函数。项目经理希望能够使用 AWS 在线编辑器编辑函数。不幸的是,使用 TypeScript 需要转译,这使得这成为不可能。这对项目经理来说是个大麻烦,所以我不得不恢复到常规的 JavaScript。
因此,在尝试与现有技术或框架集成时,您将难以使用 TypeScript。假设您正在使用不支持 TypeScript 的遗留系统。在这种情况下,您会发现自己处于一个棘手的境地,您必须手动将代码转换为 JavaScript 才能正常工作。这可能既费时又乏味,尤其是当您不了解两种语言的所有细微差别时。
所以,不要假设 TypeScript 可以无缝地融入您现有的工作流程;做你的研究并确保它实际上可以与你正在使用的工具一起工作,否则你可能会浪费宝贵的时间和资源。
6. 低生产率。
图片来自istockphoto.com。
🔝前往目录。
使用 Typescript 进行编码可能既缓慢又繁琐,尤其是与 JavaScript 或 Python 等更精简的语言相比。对于习惯于使用其他语言快速高效工作的其他开发人员和我来说,这可能会非常令人沮丧。
当你在黑客马拉松期间尝试快速制作原型时,你最不想做的就是处理 Typescript 的额外开销。当您试图绕过语言的限制时,这通常会导致沮丧和浪费时间。
随着时间的推移,Typescript 可能会让人非常沮丧,尤其是与其他更快速的开发语言相比。如果你想快速构建一些东西,你最好使用你钟爱的语言 Javascript。
然而,现在的问题是:生产中的 bug 怎么办?Typescript 捕捉类型错误,否则这些错误将最终出现在生产环境中。但为什么在对自己编写无错误代码的能力过于自信的开发人员中很常见呢?
7. 虚假承诺。
🔝前往目录。
另外,我不太喜欢 TypeScript,因为它是一种试图向您推销解决所有 JavaScript 问题的想法的语言。它试图取代 Javascript 作为 Web 开发的“首选”语言。我喜欢 Javascript 的原样,我不希望 TypeScript 出现并试图改变一切。
即使在假设 JS 中缺少类型是一个问题的情况下,TS 也没有解决它。你知道是谁做的吗?Java、C、C# 和其他编译语言。它们可以在编译时和运行时安全地保证强类型。解释性语言无法做到这一点。
前一段时间,Deno,一个基于 V8 引擎、Rust 和 Tokio 构建的 javascript 运行时,分享了自己使用 Typescript 的经验,结果证明这是生产力的主要障碍,并给系统增加了不必要的复杂性。在他们的文档中,他们分享了一个示例,该示例说明由于生成运行时代码的复杂性,很难了解这一点。这与该语言的承诺形成鲜明对比:它将帮助他们组织代码。虽然这在某些情况下可能是正确的,但在其他情况下似乎会产生相反的效果。
8. 缺乏灵活性。
🔝前往目录。
Typescript 是一种旨在使 JavaScript 更易于访问的语言,这就是它近年来变得如此流行的原因。不幸的是,由于其设计,TypeScript 对您可以使用该语言执行的操作施加了很多限制。它试图限制您使用 JavaScript 可以做的事情并掩盖其强大的一面,同时提供一种虚假的安全感。这对开发人员来说是极其不利的,因为他们无法探索 JavaScript 的真正力量或以他们想要或需要的方式使用它。
开发人员需要明白,缺乏灵活性并不能使他们成为更好的开发人员;事实上,它甚至可能会阻碍他们的开发过程,使他们无法真正理解 JavaScript 的工作原理以及如何有效地使用它。能力有限可能会导致无法充分发挥 JavaScript 的潜力。如果你想成为一名优秀的开发人员,你需要了解 JavaScript 及其所有功能背后的真正力量,而不是满足于 Typescript 的一个令人欣慰的谎言。
如果您真的想成为一名出色的开发人员,那么您不应该满足于一种限制您的创造力并隐藏该语言真正力量的语言。相反,您应该学习 JavaScript 并拥抱它的灵活性。只有这样,您才能真正释放您作为开发人员的潜力。
9. 滥用巨人公司。
🔝前往目录。
Typescript 得到了微软的支持,微软是世界上最大的公司之一。这意味着他们在推动自己的议程和让开发人员使用他们的技术方面拥有既得利益。这可以从他们将 Typescript 营销为使用 JavaScript 开发的“最佳”语言的方式中看出。然而,这种营销方式受到许多开发商的批评,他们认为这是一种误导,迫使人们选择他们的产品。
此外,这种类型的大企业支持可以创造一种环境,让开发人员感到有压力去遵守和使用 Microsoft 提供的技术。这会扼杀创造力,并导致关于编码解决方案的“一刀切”心态。目标应该是让开发人员能够从各种最适合他们需求的选项中进行选择,而不是被迫使用企业巨头推动的东西。
微软的策略也让开发人员感到困惑,他们可能不了解 Typescript 的所有方面,或者为什么它会比 JavaScript 等其他语言更好。像 Microsoft 这样的公司需要确保他们提供有关其产品的准确信息,以便开发人员不会对最适合他们的产品感到困惑或误导。
如果您还不知道,微软在反开源和反 Linux 方面有着悠久的历史。2001 年,他们的首席执行官史蒂夫·鲍尔默 (Steve Ballmer) 宣布 Linux 为“癌症”[ 4]。该公司赞助了 SCO 对 Linux 的版权攻击,并声称 Linux 侵犯了微软未具名的专利。微软还迫使基于 Linux 的 Android 供应商为可疑的专利索赔买单。
微软今天最大的问题之一是它参与了 Typescript。虽然该公司近年来一直在努力改善与开源社区的关系,但它的历史仍然笼罩在阴影之中。
因此,尽管 Typescript 是一种强大的编程语言,但重要的是要注意,历史上糟糕的公司支持它。
10. 聪明的开发者滥用。
🔝前往目录。
聪明的开发人员使用 Typescript 的问题是他们不必要地使代码过于复杂。这会导致一些问题,使代码难以阅读、维护和调试。此外,它可能会导致可伸缩性和性能问题。
当聪明的开发人员使用 Typescript 时,他们往往会专注于编写巧妙和复杂的代码,而不是高效和有效。这可能会导致大量时间浪费在调试上,并试图为原本可以避免的问题找到解决方案。
此外,聪明的开发人员可能会将自己的自豪感置于产品本身之上。当更简单的解决方案可用时,他们可能过于专注于创建复杂的解决方案。这可能导致解决方案实际上并没有使产品对用户或客户更好。
开发人员需要记住,首要目标应该始终是客户满意度。如果一个解决方案不能使产品对用户来说更好或更容易,那么就不值得在上面浪费时间。聪明的开发人员应该专注于创建改善客户体验的解决方案,而不是仅仅试图让自己为自己的代码感到自豪。
我们都同意,仅仅因为“聪明的开发人员”使用了某些东西并不意味着它就是一个好工具。但是,如果有那么多大型开源项目已经迁移到 TS,并告诉我这让他们的开发变得更容易,我会相信他们,尤其是因为它让我的开发变得更容易、压力更小。
11. 不是 JS 超集。
🔝前往目录。
Typescript 的主要卖点之一是它是 javascript 的超集,这意味着每个 JavaScript 程序都是有效的 TypeScript 程序。然而,在实践中,情况并非总是如此。TypeScript 既不是 JavaScript 的子集也不是 JavaScript 的超集。
例如,一段有效的 JavaScript 代码可能不是有效的 TypeScript 代码,例如:
varfoo={};foo.bar=42;
图片由作者提供。
12. 较慢的编译时间。
图片由作者提供。
🔝前往目录。
使用 Typescript 的主要问题之一是编译时间较慢。在处理需要编译的大型代码库时,这一点尤其明显。TypeScript 编译器在优化代码方面不如其他编译器高效,这意味着完成编译任务需要更长的时间。这会导致更大的文件大小和更长的等待编译器完成其工作的时间 [ 5]。
编译时间变慢的主要原因是 Typescript 的静态类型特性。这意味着编译器必须比 JavaScript 等动态类型语言的编译器做更多的工作,这会导致更长的编译周期。此外,TypeScript 编译器无法访问与 Babel 相同的优化工具,进一步增加了编译时间。因此,这也会影响我们的生产力。
Typescript 代码的编译速度可能非常慢,尤其是当您处理大型项目时。在他们的文档中,Deno 的维护者注意到在 cli/js 中更改文件需要几分钟时间,编译时间会增加。这是非常缓慢和痛苦的修改 [ 6]。作为刚开始使用该语言的人,我可以证明这是多么令人沮丧。你做了一个小改动,等待一两分钟让编译器完成,然后重复。这是一个巨大的时间沉没,很快就会变得令人沮丧。
我知道有些人更喜欢 TypeScript 提供的类型安全,但在我看来,它不值得在生产力方面进行权衡。此外,它可以通过 JSDoc 和一些 VSCode 设置来实现。
13. 额外的转译步骤。
🔝前往目录。
这个问题和上一个有点关系。作为一名 JavaScript 开发人员,您可能习惯于使用 Babel 转换代码。TypeScript 引入了一个额外的转译步骤,不幸的是,这可能会在开发速度方面造成瓶颈。编译器确实可以发现缺陷并在它们造成任何损害之前对其进行标记,但这是以每次都必须等待整个代码库被转译为代价的。这对于较大的项目来说尤其令人沮丧,因为编译时间会很快增加。
此外,TypeScript 编译器有时会生成令人困惑或难以阅读的代码。这是因为它试图为您的代码添加类型安全,这有时会导致更长或更复杂的变量名称。虽然这并不总是坏事,但它会使您的代码更难理解,尤其是对于尚不熟悉 TypeScript 约定的新开发人员而言。
14. 缺乏表现。
🔝前往目录。
如果您使用 TypeScript 编写代码,您可能会发现您的代码运行速度比预期的要慢。那是因为 TypeScript 组织/结构强加了运行时性能损失。
当您使用 TypeScript 时,您实际上是在告诉编译器以特定方式组织您的代码。当涉及到运行时性能时,该组织可能会产生问题。例如,如果您有大量对象,TypeScript 可能会为数组中的每个对象创建一个新变量。这意味着每次访问这些对象之一时,都必须在内存中查找它的变量。这在运行时可能会产生巨大的开销,并可能导致您的应用程序性能不佳。
15. 编写单元测试。
🔝前往目录。
在用 TypeScript 编写单元测试时,我经常发现自己对精确度的需求感到沮丧。使用 JavaScript,我可以简单地将具有必要属性的对象传递给测试,但使用 TypeScript,我需要定义对象的类型及其所有属性。这可能非常耗时,尤其是对于刚起步的人。因此,我更愿意在编写单元测试时使用 JavaScript。
花在定义类型和属性上的额外时间降低了我工作的整体效率。不仅如此,它还使调试和重构变得更加困难。例如,如果我需要更改测试中使用的对象的单个属性,我将不得不返回并修改类型定义和测试代码本身。如果我用 JavaScript 编写测试,则不需要这个额外的步骤。
我理解为什么 TypeScript 需要这种精度;它有助于在开发过程中增加额外的安全层,但有时会非常乏味和令人沮丧。仅出于这个原因,在编写单元测试时,我将继续选择 JavaScript 而不是 TypeScript。
16. 类型没那么有用。
🔝前往目录。
如果您来自 Java 这样的静态类型语言,您可能会认为类型总是好的。然而,在 JavaScript 中,类型实际上更多的是阻碍而不是帮助。一方面,JavaScript 是一种非常动态的语言,这意味着类型通常会妨碍灵活性。另一方面,TypeScript 中的类型系统实际上并不是那么好。
此外,对于大多数 JavaScript 应用程序来说,TypeScript 的类型系统并不是真正必需的。大多数应用程序不需要类型提供的额外安全性和灵活性,因此使用 TypeScript 会增加复杂性,而不会提供任何实际好处。因此,在开发应用程序时最好坚持使用纯 JavaScript。
TypeScript 还支持类型推断,当编译器尝试根据变量的使用方式猜测变量的类型时。这并不总是可靠的;如果编译器无法确定类型,它将默认为any. 这意味着该变量的所有类型检查都被有效地关闭了。这首先违背了使用 TypeScript 的目的。
vara:string;varb:number;letc;a='Hello World';b=5;c=a+b;console.log(c);
图片由作者提供。
17. 更重的技术债务。
图片来自istockphoto.com。
🔝前往目录。
当涉及技术债务时,当项目的范围、技术栈或架构在过程中途发生变化时,Typescript 可能是一个主要问题。技术债务将随着新功能的增加而增加,并且代码库中会添加更改。这可能会导致项目陷入技术债务的泥潭,如果及早对项目范围和设计计划进行评估,这些技术债务本可以避免。
例如,假设您决定在您的项目中使用 Typescript。你可能认为这种语言从长远来看会更容易维护,因为它比其他语言更类型安全。然而,在项目进行到一半时,您意识到不同的技术堆栈会更适合您的特定项目。您现在必须返回并将所有现有代码从 Typescript 重构到新技术堆栈中,这可能比您从一开始就选择正确的语言花费的时间要长得多。结果,您发现自己被技术债务压得喘不过气来,如果在项目开始时进行适当的规划,这些技术债务本可以轻松避免。
但是,您可能会争辩说 TypeScript 在与其他技术结合使用时特别强大。例如,Python 和 Go 是两种最常用的通用编程语言,而 Bash 通常用于较小的胶水脚本。GNU Make 经常被误用作项目入口点(make run、make build 等)。
我不会对 TypeScript 说不,因为这会迫使总是超负荷工作的运营团队编写更高质量的代码,而不是快速破解。但是,在某个时候,这些累积的债务将达到临界质量,并且将需要很长时间的停机时间来编写更多快速的 hack 来恢复。
因此,重要的是在决定使用哪种语言之前彻底评估您的项目范围和设计计划,以确保您不会进一步背负不必要的技术债务。
由于上述所有原因,仅类型代码使用起来不必要地复杂。
TypeScript 替代品。
图片由作者提供。
🔝前往目录。
好的,所以这是交易。TypeScript 是一个很棒的工具,但它并不是唯一的工具。JSDoc 是另一个可用于注释代码的工具。事实证明,微软也在使用 JSDoc 作为他们的核心 TypeScript 代码!那么,我们为什么要争论使用哪种工具呢?让我们只使用最适合我们的东西!
但是如果你想避免使用 TypeScript 怎么办?或者如果你想在不使用编译器的情况下使用 JSDoc 怎么办?在 JavaScript 中有多种类型检查和生成类型定义的选项。两个最流行的选项是 JSDoc 和 Flow。虽然 Flow 更受欢迎并且具有更多功能,但 JSDoc 是一个有效的替代方案,可以同样有效。
1. JSDoc。
🔝前往目录。
对于那些不知道的人,JSDoc 是一个 JavaScript 文档工具,它使用特殊注释为您的代码生成文档。以下是您可能选择使用 JSDoc 而不是 TypeScript 的几个原因:
JSDoc 消除了对编译器的需要。这使得编写代码以及启动和运行项目变得更加容易和快速。此外,JSDoc 通常比对应的 TypeScript 轻量级得多,使您可以专注于代码的特性和功能,而不用担心类型检查和其他复杂的语法问题。
JSDoc 使您可以更专注于代码的质量和可读性。由于您不必担心类型检查或维护复杂类型,您可以花更多的时间来完善代码的细节并确保它被正确记录。另外,使用 JSDoc,您可以轻松地向您的代码添加注释,这将帮助您理解每一段代码的用途。从长远来看,这使得调试和维护更加容易。
您可以只用 vanilla JS 编写测试并依靠 JSDoc 为您提供所需的类型。这使得为不关心类型但仍需要可靠的代码编写测试变得容易得多。JSDocs 更灵活,可以轻松定制测试用例。使用 TypeScript,您会受到其严格类型系统的限制,但使用 JSDocs,您可以轻松创建自定义测试用例或根据需要调整现有测试用例。这使得针对无法单独使用 TypeScript 测试的特定场景或边缘情况定制测试变得非常容易。
TypeScript 需要注解来生成文档。你猜对了。这意味着 JSDocs 仍然是 TypeScript 生成文档所必需的。vanilla JSDoc 和 TypeScript + 轻量级 JSDoc 所需的输入量差别很小。
您可能选择使用 JSDoc 而不是 TypeScript 的主要原因之一是几乎每个 IDE 都原生支持它。这意味着您无需安装任何其他依赖项即可让 JSDoc 正常工作。此外,JSDoc 提供了一种比简单地使用注释更强大的方式来记录您的代码。
虽然 TypeScript 是一种较新的语言,并且在最近几年获得了相当大的普及,但包括我在内的许多开发人员仍然更喜欢使用 JSDoc。虽然它不具备 TypeScript 的所有功能(在我看来约占 TS 功能的 90%),但对于我们作为 Web 开发人员来说,它仍然是一个非常有用的工具。
JSDoc 是公认的 JavaScript 文档标准。JSDoc 是一个被广泛接受和采用的标准,这使得查找使用 JSDocs 而不是 TypeScript def 文件的库变得容易得多。
如果你必须将 TypeScript 编译成 JavaScript,为什么不直接使用 JS?作为实现你所需要的东西的手段已经存在,熟悉 JavaScript 的人远远多于了解 TypeScript 的人;寻找人员更简单,与现有团队的结合更容易。
JSDoc 遵循 KISS 原则,提供简单而强大的语法,允许您简要记录代码。使用 JSDoc,您可以轻松地为您的 JavaScript 代码创建易于阅读和理解的文档。
如您所见,JSDoc 为 IDE 编写提示提供了很多优势,作为 Web 开发人员,使用它而不是 TypeScript 是明智的。它提供了对代码的精细控制,插入函数名称时需要的步骤更少,并提供了一个独立的标准来确保一切正常运行。
微软正试图创造一种说法,即解决类型问题的唯一方法是切换到 TypeScript。然而,事实并非如此。很明显,微软的决定完全是出于利润的考虑,而不是出于对开发人员或产品用户最有利的考虑。
总之,使用 JSDoc 而不是 TypeScript 可能对某些不一定需要类型安全或时间或资源有限的项目有益。但是,如果您的项目需要强类型或复杂逻辑,那么 TypeScript 可能仍然是更好的选择,以确保您的应用程序满足其要求。
2.流动。
🔝前往目录。
如果您对使用 TypeScript 不感兴趣,Flow 也是一个不错的选择。Flow 是 JavaScript 的静态类型检查器。这意味着它可以帮助您在运行代码之前捕获代码中的错误。这是非常强大的,可以帮助您避免许多潜在的问题。
与 TypeScript 一样,Flow 还允许您为变量和函数定义类型。这在难以跟踪类型的大型项目中非常有用。Flow 还具有 TypeScript 所没有的一些其他功能,例如对 React 的 propTypes 的支持。
以下是您可能选择使用 Flow 而不是 TypeScript 的几个原因:
Flow 更快:Flow 是更快编译时间的更好选择。它不仅实现了检查类型的主要目的,而且还可以提供比其竞争对手 TypeScript 更快的编译时间,因为它能够只检查您修改过的文件。这有助于提高程序的整体效率,如果您希望最大限度地提高效率和时间,Flow 将成为最佳选择。
Flow 提供更好的错误消息:您是否曾被难以破译并需要很长时间才能理解的错误消息所困扰?如果您曾经为此苦苦挣扎,Flow 可能是您的解决方案。Flow 提供了比 TypeScript 更好的错误消息;这些消息通常更短,更容易理解。亲自看看,看看使用 Flow 可以让您的编码之旅更加顺利。
Flow 的占用空间更小:在集成到项目中时,Flow 是更简单的选择。那是因为 Flow 不需要额外的依赖。与其他类型检查器不同,Flow 不会创建任何额外的文件,例如.d.ts文件。这意味着 Flow 的环境足迹要小得多,并且可以更轻松、更简单地集成到任何给定项目中。
因此,如果速度、准确性和简单性对您很重要,那么 Flow 可能是您项目的正确选择。
你应该选择哪一个?
🔝前往目录。
现在问题变成了:你应该选择哪一个?这取决于您的喜好和您想要完成的目标。Flow 更受欢迎并且具有更多功能,但 JSDoc 也是一个有效的选项。无论哪种方式,您都会对 JavaScript 代码进行某种程度的类型检查和生成,因此如果您正在处理大型项目,则值得考虑。
Javascript 的下一步是什么?
🔝前往目录。
似乎每天都有以某种方式更改 javascript 的新提案。虽然其中一些提议很棒,但我认为有一个特别可能会破坏我们所知道的语言。
静态类型是以前为 javascript 提出的东西,但它从未真正获得太多关注 [ 7]。然而,随着最近 TypeScript 和 Flow 等语言的流行,似乎越来越多的人对向 javascript 添加类型的想法持开放态度。
就个人而言,我不是静态类型的忠实拥护者。它会使代码更加冗长且难以阅读。但更重要的是,它可能会降低 javascript 的灵活性和宽容度。
现在,javascript 是一种易学易用的语言。它容错,并且足够灵活,可以以多种方式使用。但是,如果我们开始向语言添加类型,所有这一切都可能改变。
Javascript 可能会变得更像 Java,必须遵守严格的规则和规定。虽然这对某些人来说可能很好,但我认为这最终会使初学者更难使用 javascript。
因此,虽然我一般不反对静态类型的想法,但我认为如果它成为强制性的,对于 javascript 来说可能是一场灾难。让我们希望这不会发生。
结论。
🔝前往目录。
总之,作为一个谦虚的开发者,我认为 TS 很好,但它并不总是必要的或适合所有项目。您可以使用 JavaScript 和带有类型定义的 JSDoc 以及在 VS 中进行一些配置调整来实现防错和可读代码,而无需其他编译器。但归根结底,我认为这取决于与您合作的团队以及您正在处理的项目类型;如果你需要快速做事并与初级开发人员合作,那么可能需要一个建立在强大的 TypeScript 基础上的代码库来确保质量。不过,如果您有适当的代码审查和知识共享文化,其他方法可能更合适。
那么,为什么有人想使用 TypeScript 而不是 javascript?在我看来,JavaScript 是编写无错误、可读和可维护代码的更好语言。虽然 TypeScript 确实提供了一些好处,但我相信 javascript 的好处超过了 TypeScript 的好处。
老实说,从 JavaScript 到 Typescript 就像从 PHP 到 C#。核心概念保持不变。但是,您要添加一个类型安全层和一个额外的编译步骤。
归根结底,是否选择讨厌 Typescript 完全取决于您。但是,如果您正在寻找一种可靠的方法来编写代码,让您的应用程序在未来几年内保持正常运行,那么不可否认,学习如何使用它是一项非常宝贵的技能。所以暂时不要放弃它;继续编码并对自己的知识保持谦虚!