TypeScript全栈工程实战-(Nuxt. js & Nest. js) - 九、《TypeScript》

1,134 阅读9分钟

1567861669077.jpg

一、前言

在实际业务开发中,会遇到这样一种需求,使用VUE的页面需要支持SEO,同时对首屏有指标性要求,目前市面上普遍使用的是Nuxt.js解决方案,在引入的同时还需要考虑与现有的全栈工程结合,本系列文章探讨的是此类全栈工程的解决方案,同时使用的是TypeScript应用于前后端编程,文章中介绍的工程与技术要点源码已上传至Github,有需要的朋友可自行下载:
Nuxt.js和Nest.js同构工程


文章意在抛砖引玉,前后端使用同一种语言TypeScript编写,示例已包含基本接口请求,数据库连接应用,公用模块封装等实际开发中使用到的内容。

效果预览:

Nuxt.js与Nest.js同构工程
以下为该系列文章入口列表:
TypeScript全栈工程实战-(Nuxt. js & Nest. js) - 一、《简介》

TypeScript全栈工程实战-(Nuxt. js & Nest. js) - 二、《框架融合》

TypeScript全栈工程实战-(Nuxt. js & Nest. js) - 三、《配置服务》

TypeScript全栈工程实战-(Nuxt. js & Nest. js) - 四、《UI系统》

TypeScript全栈工程实战-(Nuxt. js & Nest. js) - 五、《API服务设计》

TypeScript全栈工程实战-(Nuxt. js & Nest. js) - 六、《SEO功能实现》

TypeScript全栈工程实战-(Nuxt. js & Nest. js) - 七、《Vuex使用》

TypeScript全栈工程实战-(Nuxt. js & Nest. js) - 八、《接入Mongo DB服务》

TypeScript全栈工程实战-(Nuxt. js & Nest. js) - 九、《TypeScript》

TypeScript全栈工程实战-(Nuxt. js & Nest. js) - 十、《工程化部署》

二、引入TypeScript意义

  • 智能提错
    开发过程中对对像是否存在某一属性动态检测并提示。

  • 类型推断
    最明显示的例子是避免JS中数字与字符串类型相加,互相赋值情况,在TypeScript中会进行赋值类型推断

  • 静态输入
    静态类型化在开发人员编写脚本时检测错误。查找并修复错误,允许开发人员编写更健壮的代码并对其进行维护,以便使得代码质量更好、更清晰。

  • 大型的开发项目
    有时为了改进开发项目,需要对代码库进行小的增量更改。这些小小的变化可能会产生严重的、意想不到的后果,因此有必要撤销这些变化。使用TypeScript工具来进行重构更变的容易、快捷。

  1. 更好的协作
    当发开大型项目时,会有许多开发人员,此时乱码和错误的机也会增加。类型安全是一种在编码期间检测错误的功能,而不是在编译项目时检测错误。这为开发团队创建了一个更高效的编码和调试过程。

  2. 更强的生产力
    干净的 ECMAScript 6 代码,自动完成和动态输入等因素有助于提高开发人员的工作效率。这些功能也有助于编译器创建优化的代码。

三、实际开发中使用示例


  • 与ES6一样,使用class关键字,可以继承,并且可以实现接口

  • 接口
    TypeScript里,接口的作用就是为这些类型命名和为代码或第三方代码定义契约

  • 继承
    类继承体现自单继承,但有个例外,接口支持多继承。

  • 多态
    多态定义接口的多种不同的实现方式,允许将子类类型的指针赋值给父类类型的指针。

  • 强类型定义
    对类成员属性、方法。变量常量定义等进行类型声明

  • 基础类型

类型 描述 示例
布尔 true/false值 let isDone: boolean = false;
数字 浮点数,除了支持十进制和十六进制字面量,还支持ECMAScript 2015中引入的二进制和八进制字面量。 let decLiteral: number = 6;
字符串 使用 string表示文本数据类型。 使用双引号( ")或单引号(')表示字符串。 let name: string = "bob";
数组 表示由此类型元素组成的一个数组 let list: Array = [1, 2, 3];
无组Tuple 元组类型允许表示一个已知元素数量和类型的数组,各元素的类型不必相同。 let x: [string, number];
枚举 enum类型是对JavaScript标准数据类型的一个补充。 像C#等其它语言一样,使用枚举类型可以为一组数值赋予友好的名字。 enum Color {Red, Green, Blue}
Any 为那些在编程阶段还不清楚类型的变量指定一个类型,跳过编译器类型检查 let notSure: any = 4;
Void void类型像是与any类型相反,它表示没有任何类型。 function warnUser(): void { .. }
Null、Undefined undefined和null两者各自有自己的类型分别叫做undefined和null。 和 void相似,它们的本身的类型用处不是很大: let u: undefined = undefined;
Never never类型表示的是那些永不存在的值的类型。 function error(message: string): never { .. }
Object object表示非原始类型,也就是除number,string,boolean,symbol,null或undefined之外的类型。 declare function create(o: object
  • 枚举类型
    使用枚举我们可以定义一些带名字的常量。 使用枚举可以清晰地表达意图或创建一组有区别的用例。 TypeScript支持数字的和基于字符串的枚举。
枚举类型 举例
数字枚举 enum Direction {Up = 1}
字符串枚举 enum News {First = 'hot'}
异构枚举 enum BooleanLikeHeterogeneousEnum { No = 0, Yes = "YES"}

  • 函数、访问控制符
    函数是JavaScript应用程序的基础。 它帮助我们实现抽象层,模拟类,信息隐藏和模块。 在TypeScript里,虽然已经支持类,命名空间和模块,但函数仍然是主要的定义 行为的地方。 TypeScript为JavaScript函数添加了额外的功能,让我们可以更容易地使用。

    和JavaScript一样,TypeScript函数可以创建有名字的函数和匿名函数。 我们可以随意选择适合应用程序的方式,不论是定义一系列API函数还是只使用一次的函数。
访问控制符 说明 示例
public(默认)) 公有,可以在任何地方被访问。 public async getList(): Promise { .. }
protecte 受保护,可以被其自身以及其子类和父类访问。 protected async getList(): Promise { .. }
private 私有,只能被其定义所在的类访问。 private async getList(): Promise { .. }
  • 泛型 像C#和Java这样的语言中,可以使用泛型来创建可重用的组件,一个组件可以支持多种类型的数据。 这样用户就可以以自己的数据类型来使用组件。

  • 模块
    从ECMAScript 2015开始,JavaScript引入了模块的概念。TypeScript也沿用这个概念。

    模块在其自身的作用域里执行,而不是在全局作用域里;这意味着定义在一个模块里的变量,函数,类等等在模块外部是不可见的,除非明确地使用export形式之一导出它们。 相反,如果想使用其它模块导出的变量,函数,类,接口等的时候,必须要导入它们,可以使用 import形式之一。

    模块是自声明的;两个模块之间的关系是通过在文件级别上使用imports和exports建立的。 模块使用模块加载器去导入其它的模块。 在运行时,模块加载器的作用是在执行此模块代码前去查找并执行这个模块的所有依赖。 大家最熟知的JavaScript模块加载器是服务于Node.js的 CommonJS和服务于Web应用的Require.js。

    TypeScript与ECMAScript 2015一样,任何包含顶级import或者export的文件都被当成一个模块。相反地,如果一个文件不带有顶级的import或者export声明,那么它的内容被视为全局可见的(因此对模块也是可见的)。
    1.导出

    2.导入

  • tsconfig.json
    1.概述
    如果一个目录下存在一个tsconfig.json文件,那么它意味着这个目录是TypeScript项目的根目录。 tsconfig.json文件中指定了用来编译这个项目的根文件和编译选项。 一个项目可以通过以下方式之一来编译:

    使用tsconfig.json
    不带任何输入文件的情况下调用tsc,编译器会从当前目录开始去查找tsconfig.json文件,逐级向上搜索父目录。 不带任何输入文件的情况下调用tsc,且使用命令行参数--project(或-p)指定一个包含tsconfig.json文件的目录。 当命令行上指定了输入文件时,tsconfig.json文件会被忽略

  • tslint
    TSLint是硅谷企业Palantir的一个项目,它是一款可以检查TypeScript代码可读性、可维护性以及功能性错误的静态检查工具,当前许多编辑器(Editors)和构建系统(Build Systems)支持这一工具,同时支持自定义编写Lint规则、配置、格式化等。

    当前TSLint已经包含了上百条规则,这些规则构筑了当前TSLint检查的基础。在代码开发阶段中,通过这些配置好的规则可以给工程一个完整的检查,并随时可以提示出可能存在的问题。

    参考: React Native工程中TSLint静态检查工具的探索之路
    在本示例中,tslint,继承自腾讯alloy团队默认配置,在其基础上进行针对性的改造,基本配置如下:

    主要增加了强方法类型声明,访问控制符声明等团队统一定约束。

四、优势

TypeScript 可以使用 JavaScript 中的所有代码和编码概念,TypeScript 是为了使 JavaScript 的开发变得更加容易而创建的。
例如,TypeScript 使用类型和接口等概念来描述正在使用的数据,这使开发人员能够快速检测错误并调试应用程序。

  • TypeScript 从核心语言方面和类概念的模塑方面对 JavaScript 对象模型进行扩展。
  • JavaScript 代码可以在无需任何修改的情况下与 TypeScript 一同工作,同时可以使用编译器将 TypeScript 代码转换为 JavaScript。
  • TypeScript 通过类型注解提供编译时的静态类型检查。
  • TypeScript 中的数据要求带有明确的类型,JavaScript不要求。
  • TypeScript 为函数提供了缺省参数值。
  • TypeScript 引入了 JavaScript 中没有的“类”概念。
  • TypeScript 中引入了模块的概念,可以把声明、数据、函数和类封装在模块中。

Typescript相对于ES系列有以下改善:

  • 类型
  • 注解
  • 模块导入
  • 语言工具包(比如,结构)
  • Typescript相对于ES6,TypeScript最大的改善是增加了类型系统。

总结:
TypeScript 的价值并不在于编写更少的代码,其价值在于编写更加安全的代码。从长远看来,它能帮助我们利用其工具识别问题并自动填充参数、属性、函数以及更多东西(通常被成为自动补全和智能感知),从而更有效率的编写出代码。