// TypeScript 是JavaScript的“超集” //前端
// 前端语言中冉冉升起的新星 //编程
TypeScript是一种由微软开发的、开源的编程语言,近两年发展迅猛,愈来愈多的JavaScript项目正在迁移到TypeScript,主流前端框架及Node.js对TypeScript的支持也愈来愈友好。自2012年10月发布首个公开版本以来,它已获得了人们的普遍承认。json
TypeScript发展至今,已经成为不少大型项目的标配,其提供的静态类型系统,大大加强了代码的可读性及可维护性;同时,它提供最新的和不断发展的JavaScript特性,能让咱们构建更健壮的组件。安全
然而在TypeScript中,有些地方对“开箱即用”进行了限制,例如当使用一个未被声明过的变量时(固然,你能够为外部系统使用声明文件)。也就是说,传统的编程语言在类型系统容许与不容许之间存在明显的边界。前端框架
TypeScript不一样于传统的编程语言,它可让你本身设置类型系统的边界。这其实是为了让你可以使用你喜欢的JavaScript,并尽量安全地使用它。前端工程师
在TypeScript中,有不少选项均可以精确地控制此边界,下文选自**《深刻理解TypeScript》**一书,如今就让咱们去了解它们吧。框架
▼▼▼编程语言
选项为boolean的compilerOptions,能够被指定为tsconfig.json下的compilerOptions。函数
{ "compilerOptions": { "someBooleanOption": true } }
或者使用命令行。工具
tsc --someBooleanOption
▼▼▼
有些代码没法被推断,或者推断它们可能会致使意外的错误。一个很好的例子就是函数参数,若是没有对它们进行注解,那么你将不清楚哪些是有效的。
functionlog(someArg) { sendDataToServer(someArg); } // 参数是什么,下面哪一个是不正确的 log(123); log('hello world');
所以,若是你没有注解函数的参数,TypeScript将会认为它是any类型的,并将继续执行。在这种状况下,将会关闭类型检查,这是JavaScript开发人员所指望的。可是这可能会让那些对安全性要求较高的人措手不及。所以,这里有一个noImplicitAny选项,当开启这个选项时,它将会标记没法被推断的类型的状况,以下所示。
functionlog(someArg) {// 错误:someArg是any类型的 sendDataToServer(someArg); }
固然,你能够继续进行注解。
functionlog(someArg: number) { sendDataToServer(someArg); }
若是真的想抛弃安全性,你能够把它标记为any。
functionlog(someArg: any) { sendDataToServer(someArg); }
▼▼▼
在默认状况下,null和undefined能够被赋值给TypeScript中的全部类型。
let foo: number = 123; foo = null; // 能够 foo = undefined; // 能够
这顺应了大多数编写JavaScript的人的习惯。可是,同时TypeScript容许你明确指出能够分配给null/undefined的内容。
在严格的null检查模式下,null和undefined是不一样的。
let foo = undefined; foo = null; // 不能够
假设有一个接口Member,以下所示。
interface Member { name: string, age?: number }
并非全部的Member都会提供年龄,因此age是一个可选属性,也就是说age的值可能为undefined。
undefined是“万恶之源”,它一般会致使运行时错误。(编写在运行时抛出错误的代码很容易。)
getMember() .then(member: Member =>{ conststringifyAge = member.age.toString() //toString属性可能undefined })
可是在严格的null检查模式下,这个错误将会在编译时被捕获。
getMember() .then(member: Member =>{ conststringifyAge = member.age.toString() // 对象可能undefined })
在一个类型检查没法得出结论的上下文中,一个新的!表达式后缀操做符,能够用来断言运算对象是非null和非undefined的,示例以下。
// 用--strictNullChecks进行编译 functionvalidateEntity(e?: Entity) { // 若是e是null或其余无效的实体,则抛出错误 } functionprocessEntity(e?: Entity) { validateEntity(e); let a = e.name; // 错误:e多是null let b = e!.name; // 能够,咱们已经断言e是非null }
注意,它只是一个断言,就像类型断言同样,你须要确保该值不为空。一个非null的断言实质上意味着你在告诉编译器“我知道它不是null,可是请让我使用它,即便它不是null”。
TypeScript将会对类中未初始化的属性抛出错误。
class C { foo: number; // 能够,已经在构造器中初始化 bar: string = "hello"; // 能够,已经初始化 baz: boolean; // 错误:属性baz没有初始化,也没有在构造器中被赋值 constructor() { this.foo = 42; } }
你可使用明确赋值断言,在属性名后加后缀,来告诉TypeScript你已经在其余地方(不是在构造器中)对它进行了初始化。
class C { foo!: number; // 注意这个感叹号 // 这是明确赋值断言操做符 constructor() { this.initialize(); } initialize() { this.foo = 0; } }
你也能够将此操做符与变量声明一块儿使用。
let a: number[]; // 没有断言 let b!: number[]; // 断言 initialize(); a.push(4); // 错误:变量在赋值以前被使用 b.push(4); // 能够:由于被断言 functioninitialize() { a = [0,1,2,3]; b = [0,1,2,3]; }
就像全部的断言同样,你在告诉编译器让它相信你,让编译器再也不抛出错误,即便代码并无被分配属性。
做为JavaScript的“超集”,TypeScript静态类型检查让咱们能轻松地构建和维护大型的前端项目。《深刻理解TypeScript》一书是 TypeScript Deep Dive 的中文版,全面阐述了TypeScript的各类“魔法”,示例丰富,简单易懂,而且对初学者很是友好!
本书从实际应用场景出发,对TypeScript语言进行深度剖析,并结合代码示例讲解了诸多TypeScript高级编程技巧,以及在实际开发工做中的最佳实践方案,能帮助读者更加透彻地理解TypeScript。
█ 与官方文档相比,本书主要有如下几个特色
█ 关 于 做 译 者
Basarat Ali Syed
TypeScript专家,微软JavaScript/TypeScript的MVP贡献者。他是TypeScript社区受人尊敬的成员,澳洲Picnic software高级开发人员,在DefinitelyTyped团队工做。Basarat常常参加澳大利亚与前端开发技术有关的会议,在多个技术活动中作过演讲。Basarat还著有Beginning Node.js 一书,目前该书已被下载39000屡次,在亚马逊、豆瓣等平台获得了读者的一致好评。
郭文超:TypeScript深度爱好者,经常使用笔名三毛,公众号 FENews 主要维护者。曾在 TutorABC、eBay 任职,目前在千寻位置担任前端工程师。对 TypeScript、React、Vue 等有较深理解。
何小磊:山西能快科贸CTO,有十年以上软件开发经验。
柳星:TypeScript 重度用户,经常使用网名 S1ngS1ng,是 freeCodeCamp 中文社区的维护者之一。曾在 Rackspace、VMware、Apple 任前端工程师一职。
徐野:携程AI研发部前端工程师。热爱大前端,爱折腾新鲜技术,精通 TypeScript、React、Node 等前端技术。
█ 目 录 结 构
本文由博客一文多发平台 OpenWrite 发布!