【彻底吃透】typeScript,持续更新...
想必很多童鞋日常工作中光堆业务,不能系统性的吃透ts,所以在此系统性的建立起对ts的认知!
结构梳理
思维导图地址(建议直接点过去看,脑图清晰) www.processon.com/view/link/6…
类型
类型注解
- 语法:(变量/函数)type
- 作用:相当于强类型语言中的类型声明
基础类型
-
布尔 let bool:boolean = true
-
数字 let num:number = 2
-
字符串 let str:stirng = '1'
-
数组
- 指定类型数组 let arr:number[] = [1,2] 等价于 let: Array= [1,2]
- 联合型数组 let mixArr: Array = [1, '1']
-
元祖 let num_str: [number, string, object] = [1, '2', {}]
-
对象 obj: {name: number | string, age: number} = {name: 1, age: 12}
-
标识符 let sym:symbol = Symbol()
-
函数 function add (x: Array, y: string): string { return x + y}
-
undefined let un:undefined = undefined
默认情况下 null 和 undefined 是所有类型的子类型。也就是说你可以把 null 和 undefined 赋值给 number 类型的变量。
-
null let nu:null = null
-
void 表示没有任何类型
当一个函数没有返回值时,你通常会见到其返回值类型是 void: function warnUser(): void { console.log('This is my warning message'); } 声明一个 void 类型的变量没有什么大用,因为你只能赋予它 undefined 和 null 。
-
any
任意类型,不建议使用any
-
never
never 类型表示没有返回值得类型(死循环,抛出异常函数等),是任何类型的子类型,也可以赋值给任何类型;然而,没有类型是 never 的子类型可以赋值给 never 类型(除了 never 本身除外)。即便 any 也不可以赋值给 never 。
-
Object
object 表示非原始类型,也就是除了 number , string , boolean , symbol, null 或 undefined 之外的类型。
枚举类型
一组有名字的常量集合 enum Cla { name = 2, age } 枚举成员特性:不能更改成员,只可读 枚举成员类型包含三种形式:没有初始值的情况 对已有枚举成员的引用 常量表达式 enum str { str1 = 'fwe' } enum Pa { b, // 初始值 a = str.str1, // 引用 c = 2 - 2, // 表达式 d = Math.random() } console.log(
-
数字枚举
实现原理:反向映射 enum Num { ops }
-
字符串枚举
不能实现反向映射 enum Str { str1 = 'fwe' }
-
异构枚举
数字和字符串混用 enum St{ a, b = '2' }
-
常量枚举
用const 声明的枚举; 作用:只需要对象的值时可以用
- 特性:在编译阶段会被移除
接口(interface)
作用:起到一种限制和规范的作用
对象类型接口
例:定义后台返回的list数组:
interface List
{ readonly name: string, age: number }
interface Data { res: List[] }
let data = { res: [ { name: '333', age: 111 } ] }
function des (data: Data) {
data.res.map((x) => { console.log(x) // {name:'333',age:111} }) }
des(data)
如果后台返回的数组中包含在interface中未定义的字段,比如ops字段
res: [ { name: '333', age: 111, ops: 988 } ]
这时候,我们就得跳过他的类型检查; 这里有三种方法:
1.赋值给一个变量存储后台数据 用类型断言绕过类型检查:
des( {res: [ { name: '333', age: 111, ops: 988 } ]} as Data )
2. 用可选操作符: interface List { name: string, age: number, ops ?: string }
3. 字符串索引签名: 用任意的字符串去索引List,可以得到任意的结果,这样List就可以支持多个属性 interface List { name: string, age: number, [x:string]: any }
*如果不确定接口中的数据类型时,可以用可索引类型接口(字符串/数字,数字是字符串的子类型)
可索引类型签名接口
// 可索引类型签名 interface strAr { [index: number]: number } let ar: strAr = [1] *数字可索引的返回值必须为字符串的子类型
函数类型接口
-
变量定义: let get: (x: string,y: number) => string
-
interface定义: interface get {(x: string, y: number): string}
-
类型别名type定义 :type get = (x: string,y: number) => string
interface 和 type 都可以定义函数类型接口 区别在于: type:不是创建新的类型,只是为一个给定的类型起一个名字。type可以进行联合、交叉等操作,引用起来更简洁。 interface:创建新的类型,接口之间还可以继承、声明合并。
混合类型接口: interface Dos { (): any, q: string, dosGO(): any}let dosHandle: Dos = (() => {}) as DosdosHandle.q = '111'dosHandle.dosGO = () => {alert(9)}*需要用到类型推断
函数
函数参数类型定义
函数中的可选参数必须放在必选参数之后 function kops(x: string, y?:number){}...rest使用 function rests(x: number, ...rest: Array): any | void { return x + rest.reduce((x1,y1) => x1 + y1) } let result = rests(1,2) console.log(result) // 3
函数重载
- 概念:两个函数命名相同,参数和个数及类型不相同好处:使用同命名的函数,实现相似功能,解决了:不需要为了相似功能的函数而使用不同的函数名称
- 实现:1. 定义若干个同命名的函数2.根据函数类型的不同而操作不同的事情例:判断传入的参数是否为数组而执行不同操作function testNumber(...rest: Array): numberfunction testNumber(...rest: object[]): object使用上面定义的两种类型的函数重载:function testNumber(...rest: any): any { if(Array.isArray(rest[0])) { console.log(rest[0][0].name) // ops } else { console.log(rest.reduce((x: number, y: number) => x + y)) // 6 }}testNumber([{name: 'ops'}], {})testNumber(1, 2, 3)
- 重载逻辑:ts编译时会处理定义的函数列表,依次进行匹配1. function testNumber(...rest: Array): number2. function testNumber(...rest: object[]): object
转载自:https://juejin.cn/post/7040433677867679757