观点
昨天看到一篇文章在讨论有了jsdoc
就不需要Typescript
观点,这个我是不能苟同的。
Typescript
和jsdoc
怎么说呢,首先来说他们不是一类技术,Typescript
是独立的编程语言,而jsdoc
是给程序(包括文档生产工具/IDE/TSC等)读的描述性文本注释,jsdoc
可以给Ide
提供一个很好的说明文档,从实现更好的代码提示,也可以快速生成sdk文档,Typescript
是强语言类型,天生具备这些同等能力,所以大家常常会拿出来比较,甚至有了二可选其一的说法。
实际在我个人看来,Typescript
的优势也是很明显的,写业务的人感受不到,写架构的人感受非常真切,首先继承/接口实现/抽象类这些没有Typescript
的支撑通过hack
方式实现起来还是有一些别扭,还得想方设法通过jsdoc
的方式来描述继承实现之间的关系,最终需要tsc
来生成d.ts
文件来描述类型。
当谈到继承、接口实现和抽象类等概念时,TypeScript相对于JavaScript真的很酷!听着,你写业务逻辑的同学可能不太能感受到,但是你作为架构师的话,就会真切地感受到它的强大之处了。想象一下,如果没有TypeScript的支持,你得通过一些"hack"的方式来实现继承和接口,还得加上一堆"jsdoc"注释来描述它们之间的关系。最后还得借助"tsc"来生成一些"d.ts"文件来描述类型。有点别扭对吧?
那么,让我给你举个例子来展示TypeScript相对于JavaScript的优势吧!
假设你在写一个电商应用,里面有各种各样的产品:电子产品、家具、服装等等。你需要定义一个通用的产品类,然后针对每种产品类型创建具体的子类。在JavaScript中,你得用原型继承和对象字面量来达成这个目标,但是没有类型检查,问题就来了。你可能会在子类中忘记实现父类的某些方法或属性,或者不小心传错参数。
例子
而在TypeScript中,你就能用类、接口和继承来清晰地定义产品类的结构和关系了。来看看下面的代码:
typescript
interface Product {
name: string;
price: number;
getDescription(): string;
}
abstract class AbstractProduct implements Product {
constructor(public name: string, public price: number) {}
abstract getDescription(): string;
}
class ElectronicProduct extends AbstractProduct {
constructor(name: string, price: number, public brand: string) {
super(name, price);
}
getDescription(): string {
return `Brand: ${this.brand}, Name: ${this.name}, Price: ${this.price}`;
}
}
class FurnitureProduct extends AbstractProduct {
constructor(name: string, price: number, public material: string) {
super(name, price);
}
getDescription(): string {
return `Material: ${this.material}, Name: ${this.name}, Price: ${this.price}`;
}
}
const laptop = new ElectronicProduct("Laptop", 1000, "Apple");
const chair = new FurnitureProduct("Chair", 200, "Wooden");
console.log(laptop.getDescription());
console.log(chair.getDescription());
看到了吗?我们使用了抽象类AbstractProduct
作为产品的通用模板,同时定义了Product
接口来描述产品的属性和方法。然后,我们创建了具体的子类ElectronicProduct
和FurnitureProduct
,它们继承自AbstractProduct
并且实现了getDescription
方法。
TypeScript的类型检查能够在编译时就帮你发现潜在的错误和不一致性。你可以确保每个子类都正确地实现了父类的方法和属性,而且在使用时还能获得准确的类型推断和代码补全提示。这样一来,你的代码结构更清晰,减少了错误的机会,而且还提高了代码的可维护性和可读性。
过往
曾经我也是一个Typescript
的反对者,因为我一直认为Typescript
非要把弱语言类型折腾成为强语言类型,这是一种内卷(可能当下还是有很多持有支持此观点的朋友),但现在我的观点改变了,下边就说一下我的经历吧。
03年初的时候我曾写过一个nodejs的web freamwork,它目前包括所有与HTTP相关的功能、自定义中间件、缓存驱动程序、文件上传和下载、自定义命令行界面、自定义路由、HTTP客户端、日志记录系统、Pug和Art模板引擎、环境配置、XSS过滤等,起初我坚持来用nodejs来编写,用jsdoc来描述类型和参数,但前几个月我停止来此项目的开发,原因是我希望实现的很多功能,需要大量的设计模式,而nodejs本身又太单薄,缺少强大的注解能力,缺少接口实现继承的特性,外部引入的库类型描述困难等等,这是我放弃的主要原因,因为我无法确保我的代码能给使用着提供足够安全严谨的提示和扩展。
github.com/fanqie/tank... 该仓库是上边提到的freamwork,这是一个积极快乐的开发维护过程。
总结
放弃的原因,只有一个,我需要Typescript
,因为Typescript
天生就可以解决这些问题,因为Typescript
本事并不是js,而是一门独立的编程语言(当然官方定义TypeScript是JavaScript的超集),要说Typescript
和javascript
关系吧,我总结一下大概有几个特征:
Typescript
最终会编译为ES5
或更高版本的JavaScript
代码- 如果要在浏览器端较低版本运行,都要编译成为
ES5
才能运行 Nodejs
和Javscript
虽然是基于v8内核,但是Nodejs
无法在浏览器端运行Typescript
无法独立运行,可以编译为Nodejs
或上边说的ES5
规范的js才能在V8引擎的独立运行时环境或浏览器端的Javascript
环境运行。