元组
元组定义需要指定每一个元素的类型:
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) {
}
- const则会编译为常量
var code = 0;
if (code === 0 /* Types.success */) {
}
反向映射
即可以通过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
- never在ts中表示永远无法到达的类型,如
let num: number & string
function fu():never {
// while(true) {
//
// }
throw new Error()
}
- never类型属于最底层的类型,当使用联合类型的时候会被忽略
let a:number | never
- 可以作为一个兜底的逻辑,防止出错
type A = '唱' | '跳' | 'rap' | '篮球'
function kun(value: A) {
switch (value) {
case '唱':
break
case '跳':
break
case 'rap':
break
// case '篮球':
// 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) // false
console.log(Symbol.for('1') === Symbol.for('1')) // true
- 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]
// 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)
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)
}