TypeScript概述
ts编译器
运行程序就是让运行时计算由编译器从源码解析得来的AST(抽象语法树)生成的字节码。所以其大致流程是:源码 - AST - 字节码 - 机器运行。
- typescript不能直接运行,需先转译成javascript来运行。所以TS执行时是JS,其类型信息都不存在了。
- typescript的类型信息检查是在编译阶段进行的。
TS的类型检查
TypeScript编译器生成TS-AST之后,TSC会对代码做类型检查,检查通过后再将其转换为js代码。
重申:TSC把typescript编译成javascript时,已经不存在类型信息了。类型检查是在编译阶段进行的。
TS的类型系统
-
ts是结构类型,就是说类型是一种结构检查器。被赋的值需满足类型的结构要求即可,不需要是其类型的子类。
-
ts有两种类型系统。可以显式的注解类型,也可以隐式的推导类型。基本类型用隐式推导更为方便,对象类型显式声明更为方便。
TS下不再自动转换类型
ts通过类型检查阻止了类型间的自动转换。所以不存在假性值了,需显式的传递布尔值。
- 如果执行可能不正确的操作,ts会报错。然而,如果明确表明意图,ts则不会做出阻拦。
- js的隐式转换可能导致难以追踪的错误,令很多js程序员深恶痛绝。
何时检查类型?
tsc在ts源码转换成ts-ast后检查了其类型信息,就是说在编译阶段检查了其类型信息。
何时报告类型错误?
在写代码时就能知道类型错误信息了。
另外:运行时错误无法在ts编译时捕获,运行时没有了ts的类型信息。
tsconfig配置选项
- include:tsc在哪个文件夹下寻找ts文件。
- lib:tsc假定运行代码的环境中有哪些API。
- module:tsc会把代码编译成哪个模块系统(commonjs, es2015等)
- outDir:tsc生成的js代码的放置目录。
- strict:检查无效代码时尽量严格。该选项强制所有代码都正确声明了类型。
- target:tsc把代码编译成哪个版本的js代码。(ES5,ES2015等)
当然还有很多其他配置选项,更多请查看ts的官方文档。
类型解析
- TS里不存在类型的隐式转换,就是说不存在假性值。需显式的给目标类型值。
- TS类型是一个约束,约束了值及其可执行的操作。
- 什么类型就有什么样的值,就有什么样操作。
类型术语
TS类型方面,基本类型用隐式推导好,对象类型用显式声明好。
any
- 表示任何类型,可执行任何操作。tsc不会对其进行类型结构信息检查。
- any没有了TS类型的约束,可像js那样做任何操作。
- any用来描述接口返回格式还是很有用的。
- typescript项目都应开启严格模式 strict。
unknown
- 表示不知道什么类型,可以是任何值,但得做类型细分后才能确定其可执行的操作。
- unknown的值得先做类型的细分。
boolean
- 就是布尔值。关键的在于TS里的布尔值没有真性值,假性值了。因为TS不再自动的转换类型了。
- boolean的效果和 true | false 并集的效果一样。
number
- 就是数字类型值。包括整数,浮点数,正数,负数,Infinity,NaN等。
string
- 就是字符串
symbol
- 就是符号类型
const声明的基本类型变量会隐式的推到为类型字面量
对象
- 对象类型如果采用隐式方式声明,则默认推导为Object。这个类型只表明其是个对象,没啥额外作用了。
- 显式的指明对象的类型较好。
- 对象类型是结构检查器,就是说只要结构符合要求即可,即使类型间不存在继承关系。
- 声明为Object类型没啥作用,值是空的,操作上只能用Object类上存在的方法。
对象类型的隐式推导
let a = { x: 'xxx' }
// 那变量a的类型会隐式推导为 { a: string }
对象的隐式推导会推断为已存在属性的类型信息,很多时候这个功能不实用,容易在投入使用时产生类型冲突。
类型字面量
严格上叫类型字面量是对象类型的子集,类型字面量会要求结构完全符合(属性上不多也不少),对象类型是结构检查器(属性上至少得满足)。更多时候让IDE提示就足够了。
let a: { field: string } = { field: 'value' }
索引
描述对象内的属性类型及其值类型。
[_: KeyType] : ValueType
犹如 Record<KeyType, ValueType>效果一样
重点:
-
首先属性名只有两种类型,字符串类型和符合类型。就是说KeyType只要不是符号,那都是字符串索引的子集。
-
常说:数字索引是字符串索引的子集。就是说:数字索引的值一定能赋值给字符串索引。
-
readonly, const 声明的都是浅不变性。