元组
元组定义需要指定每一个元素的类型:
| let arr:[number, boolean] = [1, true] |
| arr[0] = 2 |
越界则推断为交叉类型
| let arr:[number, boolean] = [1, true] |
| arr.push(2) |
| console.log(arr) |
如果不想修改,不能使用const(只是元组不可变,内容仍能够修改),需要标识为read Only
| let arr: readonly [number, boolean] = [1, true] |
| arr.push(2) |
| console.log(arr) |
添加?则推断为联合类型
| let arr: readonly [x:number, y?:boolean] = [1] |
| console.log(arr) |
即y: boolean | undefined
获取元素类型
| let arr: readonly [x:number, y?:boolean] = [1, true] |
| type first = typeof arr['length'] |
枚举
数字枚举
| enum Color { |
| red, |
| blue, |
| green |
| } |
| |
| console.log(Color.red) |
| console.log(Color.blue) |
| console.log(Color.green) |
数字枚举默认值为 0, 1, 2
增长枚举
| enum Color { |
| red = 3, |
| blue, |
| green |
| } |
| |
| console.log(Color.red) |
| console.log(Color.blue) |
| console.log(Color.green) |
增长枚举按照第一个值进行递增
字符串枚举
字符串无法递增,需要全部定义
异构枚举
即混合类型元素的枚举
接口枚举的混合使用
| enum Color { |
| red = 3, |
| blue, |
| green |
| } |
| |
| interface A { |
| color: Color.red |
| } |
| |
| let obj:A = { |
| color: Color.red |
| } |
以此约束接口定义
const枚举
| enum Types { |
| success, |
| fail |
| } |
| let code:number = 0 |
| if(code === Types.success) { |
| |
| } |
| var Types; |
| (function (Types) { |
| Types[Types["success"] = 0] = "success"; |
| Types[Types["fail"] = 1] = "fail"; |
| })(Types || (Types = {})); |
| var code = 0; |
| if (code === Types.success) { |
| } |
| var code = 0; |
| if (code === 0 ) { |
| } |
反向映射
即可以通过value获取key值
| enum Types { |
| success, |
| fail |
| } |
| let num:string = Types[0] |
| console.log(num) |
success
类型推断
- 声明的时候进行赋值,会被推断为后面赋值的类型
- 声明的时候不进行赋值,会被推断为any
type 类型别名
| type s = string | number |
| let str:s = "123" |
甚至是函数、对象、数组
| type f = (name:string, age:number) => void |
type和interface的区别
- type不能像interface一样继承,只能通过&交叉类型
- interface不能像type一样使用联合类型
type中的extends
type中的extends是包含的意思,如下1是number的子集,所以三目表达式返回的是1
| type num = 1 extends number ? 1 : 0 |
| |
| let number:num = 2 |
子集排列顺序为:
| 1 any unkown |
| 2 Object |
| 3 Number |
| 4 number string |
| 5 never |
never
| function fu():never { |
| |
| |
| |
| throw new Error() |
| } |
- never类型属于最底层的类型,当使用联合类型的时候会被忽略
| type A = '唱' | '跳' | 'rap' | '篮球' |
| |
| function kun(value: A) { |
| switch (value) { |
| case '唱': |
| break |
| case '跳': |
| break |
| case 'rap': |
| break |
| |
| |
| default: |
| const error: never = value |
| break |
| } |
| } |
| |
正常情况下,写完所有的case,default永远不会到达,否则就会报错
symbol类型
- value = Symbol(key)会为key(可以重复)生成一个唯一的value
- Symbol.for(number | string | undefined)会从symbol查看是否使用过相同的key,用过则直接返回value没有则生成新value
| let a1:symbol = Symbol(1) |
| let a2:symbol = Symbol(1) |
| console.log(a1 === a2) |
| console.log(Symbol.for('1') === Symbol.for('1')) |
- Symbol本质是一个key-value键值对的key,只不过它允许两个key重复
| let a1:symbol = Symbol(1) |
| let a2:symbol = Symbol(1) |
| |
| |
| let Obj = { |
| name: 'zhangsan', |
| [a1]: '123', |
| [a2]: '456' |
| } |
| |
| console.log(Obj) |
由于symbol的本质是key,所以这里需要添加索引签名[]才能设置value
| PS E:\File\myNote\TypeScript> ts-node .\basis.ts |
| { name: 'zhangsan', [Symbol(1)]: '123', [Symbol(1)]: '456' } |
map set集合
set自动去重
| let set: Set<number> = new Set([1, 2, 3, 4, 5, 1, 1, 1]); |
| console.log(set) |
| PS E:\File\myNote\TypeScript> ts-node .\basis.ts |
| Set(5) { 1, 2, 3, 4, 5 } |
map键值对存储
| let map:Map<string, number> = new Map<string, number>() |
| map.set("1", 1) |
| console.log(map) |
| PS E:\File\myNote\TypeScript> ts-node .\basis.ts |
| Map(1) { '1' => 1 } |
生成器和迭代器
生成器
- done为true表示生成器结束,value既可以为同步方法也可以是异步方法
| function* gen() { |
| yield Promise.resolve('123') |
| yield 456 |
| yield 789 |
| yield 1011 |
| } |
| |
| const m = gen() |
| console.log(m.next()) |
| console.log(m.next()) |
| console.log(m.next()) |
| console.log(m.next()) |
| console.log(m.next()) |
| { value: Promise { '123' }, done: false } |
| { value: 456, done: false } |
| { value: 789, done: false } |
| { value: 1011, done: false } |
| { value: undefined, done: true } |
| |
迭代器
- 对于
数组
、map
、set
以及类似function的argument
和html的document的querySelect得到的伪数组
,原型上都包含一个迭代器:
| Symbol(Symbol.iterator): ƒ values() |
-
获取迭代器实现迭代
| let arr = [1, 2, 3] |
| |
| const each = (value: any) => { |
| let It:any = value[Symbol.iterator]() |
| |
| let next:any = {done : false} |
| while(!next.done) { |
| next = It.next() |
| if(!next.done) { |
| console.log(next.value) |
| } |
| } |
| } |
| |
| each(arr) |
| |
value[Symbol.iterator]()
value[Symbol.iterator]表示根据索引标签获取Symbol.iterator的key的value值,而这个值是一个函数
-
上面的这一段实现,正是类似于map的迭代器语法糖遍历原理
迭代器语法糖: for of
| let arr = [1, 2, 3] |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| for(let num of arr) { |
| console.log(num) |
| } |
对象类型不能使用迭代器的解决方案:自己加一个
| let obj:object = { |
| max: 5, |
| current: 0, |
| [Symbol.iterator]() { |
| return { |
| next() { |
| if(this.current == this.max) { |
| return { |
| next: undefined, |
| done: true |
| } |
| } else { |
| return { |
| value: this.current++, |
| done: false |
| } |
| } |
| } |
| } |
| } |
| } |
| for(let num of obj) { |
| console.log(num) |
| } |
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?