图标
✅ 推荐使用
🐱🐉
类型
类型是一系列值及可以对其执行的操作
如:String 类型包含所有字符串,以及可以对字符串执行的操作(+、||、&& 等),以及可以在该类型上调用的方法 (.fixed()、.toString() 等)
类型注解
function squareOf(n: number){
return n * n
}
squareOf(2) // 4
squareOf('z') // 类型“string”的参数不能赋给类型“number”的参数
// n: number 中的 : number 就是 n 参数的 类型注解,限定该参数的类型为 number 类型
any
## any
let a: any = 666
let b: any = ['danger']
let c = a + b
// 正常情况 c 将报错
unknown
如果你确实无法预知一个值的类型,不要使用 any , 应该使用 unknown,
与 any 类似,但有区别, (TS 会要求你检查,细化类型
// unknown
let a: unknown = 30
let b = a === 123
let c = a + 10
if(typeof a === 'number'){
let d = a + 10
console.log(d)
}
- ts 不会把任何值推导为 unknown 类型,必须显示注解。(a)
- unknown 类型的值可以比较。 (b)
- 但是直线操作时不能假定 unknown 类型的值为某种特定类型 (c), 必须向 TS 证明一个值确实时某个类型。
boolean
// boolean
let a = true
var b =false
const c =true
let d: boolean = true
let e: true = true
let f: true = false
为什么 c 的类型是 true?
1. 使用 const 声明的值,赋值之后便无法修改。因此TS 推导出来的是范围最窄的类型。
把类型设为某个值,就限制了 c 在所有布尔值中只能取指定的那个值。这个特性称为 类型字面量(type literal)
- 可以让 TS 推导出值得类型为 boolean(a 和 b) ✅
- 可以让 TS 推导出值为某个具体得布尔值(c) ✅
- 可以明确告诉 TS ,值得类型为 boolean (d)
- 可以明确告诉 TS,值为某个具体得布尔值(e 和 f)
number
number 包括所有的数字: 整数、浮点数、正数、负数、Infinity、NaN 等。
let a = 1234
var b = Infinity * 0.10
const c = 5678
let d = a < b
let e: number = 100
let f: 26.218 = 26.218
let g: 26.218 = 10
- 可以让 TS 推导出值得类型为 number(a 和 b) ✅
- 可以使用 const, 让 TS 推导出值为某个具体得数字 (c)
- 可以明确告诉 TS ,值得类型为 boolean (e)
- 可以明确告诉 TS,值为某个具体的数字(f 和 g)
🐱🐉 在处理较长的数字时,为了便于辨识数字,建议使用数字分隔符 。在类型和值所在的位置上都可以使用数字分隔符。
let 一百万 = 1_000_000
let 两百万: 2_000_000 = 2_000_000
bigint
bigint 时 JS 和 TS 新引入的类型, 处理较大整数时,不用再担心舍入误差。
// bigint
let a = 1234n
const b = 5678n
var c = a + b
let d = a + b
let e = 88.5n
let f: bigint = 100n
let g: 100n = 100n
let h: bigint = 100
与 Boolean 和 number 一样,声明 bigint 类型也有四种方式,尽量使用自动推导。
string
let a = 'hello'
var b = 'billy'
const c = '!'
let d = a + '' + b + c
let e: string = 'zoom'
let f: 'john' = 'john'
let g: 'john' = 'zoe'
同上
symbol
经常用于代替对象和映射的字符串建,确保使用正确的已知建
let a = Symbol('a')
let b: Symbol = Symbol('b')
var c__ = a === b
let d = a + 'x'
const e = Symbol('e')
const f: unique Symbol = Symbol('f')
let g: unique Symbol = Symbol('f')
let h = e === e
let i = e === f
- 使用 const 声明的符号,TS 推导为 unique symbol 类型。 在代码编辑器中显示为 typeof yourVariableName, 而不是 unique symbol.
- 可以显示注解 const 变量类型为 unique symbol.
- unique symbol 类型的值始终与自身相等。
- TS 在编译时知道一个 unique symbol 类型的值绝不会与另一个 unique symbol 类型的值相等。
object
let a: {
b: number //1
c?: string // 2
[key: number]: boolean // 3 索引标签
}
// 1. a 有个类型为 number 的 属性 b.
// 2. a 可能有个类型为string 的属性 c. 如果有属性c, 其值可以为 undefined.
// 3. a 可能有任意多个数字属性,其值为布尔值。
let apsa : {
[key: string]: string
} = {
'a' : 'aaa',
'b' : 'bbb'
}
let apsb: {
str: string
} = {
str: 'aaa',
stc: 'bbb'
}
let user: {
readonly firstName: string // 只读
} = {
firstName: 'cc'
}
索引标签 (翻译的怪怪的)
[key: T]: U
记住: 键的类型(T) 必须可赋值给 number 或 string. ( JS 对象的键为字符串; 数组时特殊的对象,键为数字)
对象字面量表示法有一个特例: 空对象类型 ({}). 除 null 和 undefined 之外的任何类型都可以赋值给空对象类型。(尽量避免使用)
let danger: {}
danger = {}
danger = {x : 1}
danger = []
danger = 2
- 对象字面量表示法( {a: string} ), 也称对象的结构。 如果知道对象有那些字段,或者对象的值都为相同的类型,使用这种方式。
- 空对象字面量表示法({}). 尽量避免使用。
- object 类型。 如果需要一个对象,但对对象的字段没有要求,可以使用。
- Object 类型。 尽量避免使用。
类型别名
// 给类型声明别名
// 干脆把他当作 声明 变量 的方式就完事了
type Age = number
type Preson = {
name: string
age: Age
}
type Age = string // 同一类型不能声明两次
同一类型不能声明两次
块级作用域
并集类型和交集类型
// 就是数学书里的并集和交集
| 并集
& 交集
type Cat = { name: string, purrs?: boolean }
type Dog = { name: string, barks?: boolean, wags?: boolean}
type CatOrDogOrBoth = Cat | Dog
type CatAndDog = Cat & Dog
let a: CatOrDogOrBoth = {
name: '123',
wags: true
}
let b: CatAndDog = {
name: 'sss'
}
function trueOrNull(isTrue: boolean) {
if(isTrue){
return 'true'
}
return null
}
trueOrNull(true)
数组
let a = [1,2,3]
var b____ = ['a', 'b']
let c: string[] = ['a']
let d= [1, 'a']
const e = [2, 'b']
let f = ['red']
f.push('bule')
f.push(true)
let g = []
g.push(1)
g.push('red')
let h: number[] = []
h.push(1)
h.push('red')
🐱🐉 TS 支持两种注解数组类型的语法: T[] 和 Array。 二者作用和性能无异。
数组应该保持同质 , 即保证数组中的元素都具有相同的类型。 ( why? ) (f)
与对象一样, 使用 const 声明数组不会导致 TS 推导出范围类型更窄的类型
数组离开定义时所在的作用域后,TS 将最周确定一个类型,不在扩张
function buildArray () {
let a = []
a.push(1)
a.push('x')
return a
}
let myArray = buildArray()
myArray.push(true)
元组
元组时 array 的子类型, 是定义数组的一种特殊方式,长度固定,各索引位上的值具有固定的已知类型。
声明元组时必须显示注解类型。( 因为它和数组都是使用 方括号 )
let a: [number] = [1]
// [ 名,姓,出生年份 ] 形式的元组
let b: [string, string, number] = ['陈', '贝', 1999]
b = ['陈', '贝', '贝', 1998]
// 剩余元素
// 字符串列表,至少有一个元素
let friends: [string, ...string[]]= ['Sara', 'Tali', 'Chloe']
// 元素类型不同的列表
let list: [number, boolean, ...string[]] = [1, false, 'a', 'b', 'c']
// 只读数组和元组
let as: readonly number[] = [1,2,3]
let bs: readonly number[] = as.concat(4)
let three = bs[2]
as[4] = 5
as.push(6)
元组类型能正确定义元素类型不同的列表,还能知晓该种列表的长度。这些特性使得元组比数组安全的多,应该经常使用。
null、undefined、void 和 never
类型 | 含义 |
---|---|
null | 缺少值 |
undefined | 尚未赋值的变量 |
void | 没有返回值的函数 |
never | 永不返回的函数 |
// (a) 一个返回数字或 null 的函数
function a(x: number) {
if(x < 10) {
return x
}
return null
}
// (b) 一个返回undefined 的函数
function b() {
return undefined
}
// (c) 一个返回 void 的函数
function c() {
let a = 2 + 2
let b = a * a
}
// (d) 一个返回 never 的函数
function d() {
throw TypeError ('I always error')
}
// (e)
function e() {
while (true){
doSomething()
}
}
如果说 unknown 时其他每个类型的父类型, 那么 never 就是其他每个类型的子类型。
理论上: never 类型可以赋值给其他任何类型,在任何地方都能放心使用 never 类型的值。
枚举
枚举的作用时列举类型种包含的各个值。这是一种无序数据结构,把键映射到值上。可以理解为 编译时 键固定的对象,访问键时,TS 将检查指定的键是否存在。
用的少,以后用到再补充把( 作者大大说: 由于使用枚举极易导致安全问题,因此作者建议远离枚举。 )
偷懒,嘿嘿 😎
补充
-
索引签名
-
明确赋值
let i: numberlet j = i * 3 // 在赋值前使用了变量“i”
-
使用 const 声明对像时的类型推导
使用 const 声明对象不会导致 TS 把推导的类型缩窄,这是因为 JS 对象时 可变的(属性) -
结构化类型
🐱🐉 一种编程设计风格,只关心对象有那些属性,而不管属性使用什么名称(名义化类型)。在某些语言中也叫鸭子类型 -
类型字面量
仅表示一个值的类型 -
public firstName: string
public 是 this.firstName = firstName 的简写
欢迎来到这里!
我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。
注册 关于