图标
✅ 推荐使用
🐱🐉
类型
类型是一系列值及可以对其执行的操作
如: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 的简写
欢迎来到这里!
我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。
注册 关于