TypeScript----类型

图标

✅ 推荐使用
🐱‍🐉

类型

类型是一系列及可以对其执行的操作

如: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)
  }
  1. ts 不会把任何值推导为unknown 类型,必须显示注解。(a)
  2. unknown 类型的值可以比较。 (b)
  3. 但是直线操作时不能假定 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)

  1. 可以让TS 推导出值得类型为boolean(a和b) ✅
  2. 可以让TS推导出值为某个具体得布尔值(c) ✅
  3. 可以明确告诉 TS ,值得类型为boolean (d)
  4. 可以明确告诉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

  1. 可以让TS 推导出值得类型为number(a和b) ✅
  2. 可以使用 const, 让 TS 推导出值为某个具体得数字 (c)
  3. 可以明确告诉 TS ,值得类型为boolean (e)
  4. 可以明确告诉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
  1. 使用const 声明的符号,TS 推导为 unique symbol 类型。 在代码编辑器中显示为typeof yourVariableName, 而不是 unique symbol.
  2. 可以显示注解const 变量类型为unique symbol.
  3. unique symbol 类型的值始终与自身相等。
  4. 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
  1. 对象字面量表示法( {a: string} ), 也称对象的结构。 如果知道对象有那些字段,或者对象的值都为相同的类型,使用这种方式。
  2. 空对象字面量表示法({}). 尽量避免使用。
  3. object 类型。 如果需要一个对象,但对对象的字段没有要求,可以使用。
  4. 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 将检查指定的键是否存在。

用的少,以后用到再补充把( 作者大大说: 由于使用枚举极易导致安全问题,因此作者建议远离枚举。 )
偷懒,嘿嘿😎


补充

  1. 索引签名

  2. 明确赋值
    let i: number

    let j = i * 3 // 在赋值前使用了变量“i”

  3. 使用const声明对像时的类型推导
    使用const 声明对象不会导致TS把推导的类型缩窄,这是因为JS 对象时 可变的(属性)

  4. 结构化类型
    🐱‍🐉 一种编程设计风格,只关心对象有那些属性,而不管属性使用什么名称(名义化类型)。在某些语言中也叫鸭子类型

  5. 类型字面量
    仅表示一个值的类型

  6. public firstName: string

    public 是 this.firstName = firstName 的简写

posted @ 2021-04-27 22:34  陈及北  阅读(206)  评论(0编辑  收藏  举报