Appearance
元组
定义
在单个变量中存储不同类型的值
特性:限制数组元素的个数和类型
都不确定使用 any[]
ts
let x: [string, number]
// 类型必须匹配且个数必须为2
x = ['hello', 10] // OK
x = ['hello', 10, 10] // Error
x = [10, 'hello'] // Error解构赋值
ts
let employee: [number, string] = [1, 'Semlinker']
let [id, username] = employee解构元素要小于等于元组元素个数
元素
可选元素
可选元素:通过 ? 号来声明可选元素
ts
// [variable?]
let optionalTuple: [string, boolean?]
optionalTuple = ['Semlinker', true]
optionalTuple = ['Kakuqo']剩余元素
剩余元素:代表元组类型是开放的,有零个或多个额外的元素。
ts
type RestTupleType = [number, ...string[]]
let restTuple: RestTupleType = [666, 'Semlinker', 'Kakuqo', 'Lolo']只读元素 ^3.4+^
可以为任何元组类型加上 readonly 关键字前缀,以使其成为只读元组。
ts
const point: readonly [number, number] = [10, 20]使用 readonly 后,任何企图修改元组中元素的操作都会抛出异常
void
void:没有任何类型。
ts
let a: void
let b: number = a // Error不能直接赋值,只能为它赋予null和undefined(在strictNullChecks未指定为 true 时)
方法没有返回值,定义为 void 类型,不能为 undefined
ts
function fun(): undefined {
console.log('this is TypeScript')
}
fun() // Errornever
never:永不存在的值的类型
以下两种情况无法返回值
- 函数执行时抛出了异常
- 函数中执行无限循环的代码
ts
// 异常
function err(msg: string): never {
// OK
throw new Error(msg)
}
// 死循环
function loopForever(): never {
// OK
while (true) {}
}never类型同null和undefined一样,也是任何类型的子类型,也可以赋值给任何类型。
除了 never 本身,没有类型可以赋值给 never,包括 any
ts
let ne: never
let nev: never
let an: any
ne = 123 // Error
ne = nev // OK
ne = an // Error
ne = (() => {
throw new Error('异常')
})() // OK
ne = (() => {
while (true) {}
})() // OKnever 作用:避免出现新增类型确没有具体实现
ts
type Foo = string | number
function controlFlowAnalysisWithNever(foo: Foo) {
if (typeof foo === 'string') {
// 这里 foo 被收窄为 string 类型
} else if (typeof foo === 'number') {
// 这里 foo 被收窄为 number 类型
} else {
// 利用never只能赋值为never这一特性
const check: never = foo
}
}新增 boolean 后,没有具体的实现,会将 foo 赋值为 never,会报错
ts
type Foo = string | number | booleanany
任何类型都可以被归为 any 类型。
- any 相当于 js
- 声明时,未指定其类型,默认为 any
一个普通类型,在赋值过程中改变类型是不被允许的,但是 any 可以
ts
let a: string = 'seven'
a = 7
// TS2322: Type 'number' is not assignable to type 'string'.any 访问任何属性和方法
ts
let anyThing: any = 'hello'
console.log(anyThing.myName)
console.log(anyThing.myName.firstName)
let anyThing: any = 'Tom'
anyThing.setName('Jerry')
anyThing.setName('Jerry').sayHello()
anyThing.myName.setFirstName('Cat')unknown ^3.0+^
与any一样,所有类型都可以分配给unknown:
unkonwn 与 any 区别
- any:任何类型都能赋值给 any,any 也能赋值给任何类型
- unkown:任何类型都能赋值给 unkown,但它只能赋值给 unknown 和 any
总结:unknown 只能赋值给 any、unknown 。any 无限制。
不缩小类型,就无法对unknown类型执行任何操作。可以使用typeof、类型断言等方式来缩小未知范围
ts
function getDogName() {
let x: unknown
return x
}
const dogName = getDogName()
// 直接使用
const upName = dogName.toLowerCase() // Error
// typeof
if (typeof dogName === 'string') {
const upName = dogName.toLowerCase() // OK
}
// 类型断言
const upName = (dogName as string).toLowerCase() // OK通常先声明 unknown,然后通过类型缩小来锁定具体类型
Number、String、Boolean、Symbol
Number、String、Boolean、Symbol 是相应原始类型的包装对象
原始类型兼容对应的对象类型,对象类型不兼容对应的原始类型。因此不要使用对象类型来注解值的类型。
ts
let num: number
let Num: Number
Num = num // ok
num = Num // ts(2322)报错object、Object 和 {}
object:所有非原始类型
非原始类型能赋值给 object
ts
let lowerCaseObject: object
lowerCaseObject = 1 // ts(2322)
lowerCaseObject = 'a' // ts(2322)
lowerCaseObject = true // ts(2322)
lowerCaseObject = null // ts(2322)
lowerCaseObject = undefined // ts(2322)
lowerCaseObject = {} // ok原始类型:
string、boolean、number、bigint、symbol、null和undefined
Object:所有拥有 toString、hasOwnProperty 方法的类型
所有原始类型、非原始类型都可以赋给 Object
ts
let upperCaseObject: Object
upperCaseObject = 1 // ok
upperCaseObject = 'a' // ok
upperCaseObject = true // ok
upperCaseObject = null // ts(2322)
upperCaseObject = undefined // ts(2322)
upperCaseObject = {} // ok{}:原始类型和非原始类型的集合,等同 Object
严格模式下:undefined 和 null 不能赋值给 object、Object、{}
总结:Object 和 {} 可以互换,object 只表示非原始类型