前言
在学习 TypeScript 过程中, 我也是遇到了很多的阻力, 因为并未有太多深入挖掘的场景, 之前做 IONIC 的时候, 也只是用 TS, 现如今, 这一个系列也是记录自己学习和收获, 同时希望自己的这系列教程对想要学习 TypeScript 的同学有一定的帮助, 我尽量以简洁的语言以及代码来将我的东西阐述清楚.
如果, 在文章中有错误和疏漏, 希望大家多多指出和包涵, 大家可以通过邮箱来联系我: 869345843@qq.com
什么是 TypeScript
关于 TypeScript 有一种很有趣的说法, 说 TypeScript = Typed + JavaScript, 仔细想来, 确切的说 TypeScript 应该是对 JavaScript 的扩展 + 类型系统, 所以这个公式应该是 Typed + JavaScript + Extends
而官方文档也说明了一件事情, 那就是 TypeScript 是 JavaScript 的超集, 为了让我们可以无缝从 JavaScript 切换到 TypeScript, 微软的 TypeScript 只是提供了 TypeScript 到 JavaScript 的编译, 并不包含运行时, 它的运行时也就是 JavaScript 的运行时, 所以 TypeScript 可以说是一种 JavaScript 的新的编码实现.
TypeScript 和 JavaScript 的类型
先让我们来看一下 JavaScript 的基本类型系统: Boolean,Null,Undefined,String,Number, 以及 ES6 之后, 新增的 Symbol 类型.
TypeScript 有哪些类型呢? 下面让我们来看一下 TypeScript 的基本类型: Boolean,Null,Undefined,String,Number,Symbol + TypeScript 扩展的类型.
上方 TypeScript 的基本类型正是 JavaScript 的基础类型 + 自行扩展的类型系统.
TypeScript 对于 JavaScript 的扩展类型借鉴了强类型语言的类型系统, 有 Void,Never, 泛型等以及高阶类型.
TypeScript 的表达形式
明确了 TypeScript 和 JavaScript 类型方面的差异化, 我们来看看如何将 JavaScript 改写成为 TypeScript 呢?
先上一段 JavaScript 代码:
- let str = 'Hello JavaScript'
- let num = 10
- let arr = [1, 2, 3]
- const htmlStr = `${str}_${num}_${arr.join()}`
- document.querySelectorAll('.app')[0].innerHTML = str
对于上述一段代码, 如果运行在 TypeScript 环境下, 也是可以正常运行, 因为 TypeScript 是 JavaScript 的超集, 兼容这种写法.
那么, 上面的代码, 对应 TypeScript 又是如何的呢? 下面我们用代码描述:
- let str: string = 'Hello JavaScript'
- let num: number = 10
- let arr[] = [1, 2, 3] //Array<number>
- const htmlStr = `${str}_${num}_${arr.join()}`
- document.querySelectorAll('.app')[0].innerHTML = str
由此可见, TypeScript 是更规范化的将变量类型声明化, 他的格式如下:
let variable: Type = value
TypeScript 中的数据类型
说道 TypeScript 的数据类型, 我们就可以用一段代码来展示:
- // 原始类型
- let bool: boolean = true
- let num: number = 13
- let str: string = 'abc'
- // 数组
- let arr1: number[] = [1, 2, 3]
- let arr2: Array<number> = [1, 2, 3]
- let arr3: Array<number | string> = [1, '2']
- // 元组
- let tuple: [number, string] = [0, '2'] // 特殊数组, 限定数组元组类型和个数
- tuple.push(2) // [0 , '2', 2]
- // tuple[2] // 不允许越界访问
- // 函数
- let add = (x: number, y: number): number => x + y
- let func: (x: number, y: number) => number
- func = (a, b) => a + b
- // 对象
- let obj: object = { x: 1, y: 2 }
- // obj.x = 100 // wrong
- let obj2: { x:number, y:number } = { x: 1, y: 2 }
- obj2.x = 100
- //void
- let noReturn = () => {}
- void 0 === undefined
- // any
- let x // 可以任意赋值
- // never 永远不会有返回值
- let error = () => {
- throw new Error()
- }
- // 枚举
- enum Role { // 数字 或者声明字符串
- Teacher, // 默认 0 开始以下依次 + 1
- Student, // 1
- }
TypeScript 的类型推断
当然, 我们在书写代码的过程中, 如果忘记加类型, 写出纯 JavaScript 代码, 那么 TypeScript 也会通过类型推断, 帮助我们推断出大部分类型.
比如我们最初的 JavaScript 代码, 类型推断依照代码做出如下说明:
- let str = 'Hello JavaScript'
- str = 100 // error 因为赋值操作, 已经将 str 推断为 string 类型, 这样赋值在 TypeScript 会报错
- let num = 10
- num = 'some string' // error, 此时 num 已经推断为 number 类型, 不可以将 string 类型赋值给它
- let arr = [1, 2, 3]
- arr = true // error, 类型推断为数组类型 Array<number>, 不能赋值 Boolen
- arr = ['1', '2', '3'] // error, 类型推断为 Array<number>, 不能赋值为 Array<string > 类型
- const htmlStr = `${str}_${num}_${arr.join()}`
- document.querySelectorAll('.app')[0].innerHTML = str
为什么要有类型
由上面代码可以知道, TypeScript 对代码进行了比较严格的类型判断, 那么我们肯定想问, 为什么要这样做?
其实, 这样做最大的好处, 就可以让代码简单的文档化, 并且规范我们的代码操作, 避免一些不必要的边界值问题, 这对于开发大型应用和写测试用例都有极大的帮助.
而 TypeScript 却也并未限制我们编码的自由, 就像是骑马, 如果单纯用 JavaScript 书写代码, 就好像是没有缰绳的骑马, 会让我们陷入到危险和抓狂之中, 但是有了 TypeScript, 我们就相当于是有了缰绳, 可以使得我们的代码更优雅, 也更容易控制和理解.
总结
本篇文章探讨了 TypeScript 和 JavaScript 中的类型系统, 以及在 TypeScript 中如何处理类型声明和赋值. 同时也暴露了一些灵活性的问题, 比如不能将一个字符串数组赋值给数字数组. 所以我们如果单一的想要定义一个多类型的数组就会遇到麻烦, 但这些不是问题, TypeScript 中也存在着解决方案.
在下一篇, 我们将会看看 TypeScript 是如何处理这些要求, 以及如何给予相应的类型限制和定义的.
参考资料:
TypeScript 手册: TypeScript https://www.tslang.cn/
极客时间 TypeScript 开发实战专栏: TypeScript 开发实战 https://time.geekbang.org/course/intro/211
参考书: TypeScript 实战指南 https://read.douban.com/ebook/115862002/
参考书: Leaning TypeScript 中文版 https://book.douban.com/subject/26906857/ (这本书讲解的 TypeScript 的版本为 1.5+, 不是最新版本, 如果买书, 不建议买, 可以购买上本参考书 TypeScript 实战指南)
来源: https://www.cnblogs.com/qixingduanyan/p/11415856.html