共计 2743 个字符,预计需要花费 7 分钟才能阅读完成。
TS 相干
基本概念
类型注解:ts 里的类型注解是一种轻量级的为函数或变量增加束缚的形式
根底类型
布尔值、数字、字符串、数组、元组、枚举、any、void、null、undefined、never、object
any、unknown、never、void
定义
- any:任意类型的变量
- unknown:示意未知类型
- never:永不存在的值的类型
- void:无任何类型,没有类型
unknown 与 any 相似,但应用前必须进行断言或守卫,从类型推导来讲,unknown 是最高级类型,any 是 unknown 的下一级
nerver、void 用于函数时,never 示意函数用于执行不到返回值那一步 (抛出异样或死循环) 的返回值类型,即用不存在的值的类型,而 void 则示意没有返回值,不返回或返回 undefined。从类型推导来讲,never 是最低层,void 与 any 同级
应用
- 能不应用 any 就不必
- 申明时如果不确定具体的类型,则能够应用 unknown 代替,在应用时用类型断言或类型守卫进行类型膨胀
- never 罕用于结构条件类型来组合出更灵便的类型定义
- void 罕用于示意类型没有返回值
扩大
any 与 unknown
在原先的 typescript 中,any 属于 top type(最高级类型),在 typescript3.0 中,unknown 才是 top type
如果不放大类型,就无奈对 unknown 类型执行任何操作
function getDog() {return '22'}
cosnt dog: unknown = getDog()
dog.hello() // Object is of type 'unknown'
ts 高级用法
- 接口 (interface) 能够形容一个对象或者函数
- 类(class)
- 函数
- 泛型
- 枚举
- 迭代器和生成器
- 装璜器
- 继承、多态、重载、重写
- 抽象类 & 形象办法
具体应用示例能够看官网
TS 编译原理
graph LR
源码 --> 扫描器(scanner) --> Token 流(两头产物) --> 解析器(parser) --> AST
AST --> 查看器(checker) --> 类型查看性能
AST --> 绑定器(binder) --> symbois(符号) -.- 查看器(checker) -.- 发射器
AST --> 发射器(emitter) --> javascript 代码
实线为主流程,有三条,虚线为独立流程,符号独自指向了查看器,查看器独自指向了发射器
总的来说是
graph LR
sourceCode --> 扫描仪 --> token 流 --> 解析器 --> ast
token 流和 ast 相似,是扫描之后转换代码的一个两头产物,也是一个对象,不过 key 和 value 不一样,然而总体形成是相似的
类型推论图
graph
unknown --> any
any --> null
any --> number -.- never
any --> bigint -.- never
any --> boolean -.- never
any --> string -.- never
any --> object --> array --> tuple -.- never
object --> function -.- never
any --> void --> undefined
面试题
- 以下代码 ts 推论进去的类型是什么
let a = 1024 // number
let b = '1024' // string
const c = 'apple' // null,const 类型推论进去的都是 null
let d = [true, false, true] // array,精确来说是 boolean[]
let e = {name: 'apple'} // object
let f = null // null
- 可赋值性
子集能够赋值给超集,超集不能赋值给子集,除非做出断言
function a(input: string): string {return input}
function b(iniput: string | number) {return input}
// a 能够间接赋值给 b
let input = a()
b(input)
// 断言办法 1:as 关键字
let input = b()
a(input as string)
// 断言办法 2:通过泛型固定参数类型
a(<string>input)
type 与 interface 异同
在官网文档里,形容 type 的作用是为类型起 别名,interface 则是偏重形容数据结构的(比方一个对象里蕴含了什么属性)
用法
- type
type age = number
type dataType = number | string
type method = 'GET' | 'POST' | 'PUT' | 'DELETE'
type User = {
name: string
age: number
}
// 合并 type
type name = {name: string}
type User = name & {age: string}
- interface
interface User {
name: string
age: number
}
// 合并 interface
interface Admin extends User {id: number}
// interface 也能够合并 type
type User = {
name: string
age: number
}
interface Admin extends User {id: number}
共同点
- 都能够形容一个对象或函数
- interface 和 type 都能够相互拓展,语法上不同,interface 应用
extends
关键字,type 是用&
符号
不同点
- type 能够用于其余类型(联结类型、元组类型、根本类型(原始值)),interface 不反对
type PointX = {x: number}
type PointY = {y: number}
// 联结
type Point = PointX | PointY
// 元组
type Data = [PointX, PointY]
// 原始值
type Name = Number
// typeof 的返回值
let div = document.createElement('div')
type B = typeof div
- interface 能够屡次定义,并主动合并所有成员变量,type 不反对
- type 能应用 in 关键字生成映射类型,interface 不反对
type Keys = 'firstname' | 'surname'
type DudeType = {[key in Keys]: string
}
// 等同于
type DudeType = {
firstname: string
surname: string
}
装璜器问题
执行程序
- 有多个参数装璜器时,从最初一个参数顺次向前执行,也就是说装璜器运行程序是倒序的
- 办法和办法参数中参数装璜器先执行
- 类装璜器总是最初执行
- 办法和属性装璜器,谁在后面谁先执行,因为参数是属于办法一部分,所以参数会始终紧紧挨着办法执行
接口类型
- 属性类接口
- 函数类接口
- 可索引接口
- 类类型接口
- 扩大接口
正文完