# 基本类型

Typescript的数据类型几乎与Javascript一样

# 类型注解

开始学习Typescript前,先了解下类型注解

类型注解是Typescript提供的高级功能,是一种轻量级的为函数或变量添加约束的方式,开发人员通过类型注解规定Typescript变量类型

TypeScript提供了静态的代码分析,可以分析代码结构和提供的类型注解

  // 为变量str添加类型注解': string',并设置默认值
  let str: string = 'Hello TS'
  // 重新给str赋值为number类型的值,
  // str标注有错误:不能将类型“number”分配给类型“string”。
  str = 1
  console.log(str)
  // 编译报错: Type 'number' is not assignable to type 'string'.
  // 
  function fn (str: string) {
    return `我说了'${str}'`
  }
  console.log(fn('嗨嗨~嗨~'))

# Boolean

表示true || false

let bool: boolean = false
bool = true

# Number

Typescript的数字类型也是浮点型,支持十进制/十六进制/二进制/八进制

let n1: number = 10 // 十进制
let n2: number = 0b1010 // 二进制
let n3: number = 0o12 // 八进制
let n4: number = 0xa // 十六进制

# String

用'string' || "string"表示

let str: string = 'Typescript'

# Undefined

表示未定义

let undef: undefined = undefined

# Null

表示未定义和空值

let nul: null = null

# Array

两种方式表示数组

  • 变量: 元素数据类型[] = [值, ...]
  • 变量: Array<元素数据类型> = [值, ...]
let num1: number[] = [1, 2, 3]
let num2: Array<number> = [1, 2, 3]

# Tuple

Tuple是元祖类型,用来表示已知元素数量及元素类型的数组,元素数量及元素类型在定义元组时就已经确定

❗️ 使用元组时,不论元素的类型/位置/数量,都应与元组定义时保持一致

let tupl: [string, number, boolean]
tupl = ['发际线', 0, true] // ['发际线', 0, true]
tupl = [0, true] // 报错
console.log(tupl)

可通过下标访问元素,如果正确访问元素(下标/类型正确),便可以使用类型对应的方法,否则报错

let tupl: [string, number, boolean]
tupl = ['发际线', 0, true]
console.log(tupl[0].split('')) // ['发', '际', '线']
console.log(tupl[1].split('')) // 报错,tupl[1]为number类型,没有split方法
console.log(tupl[3]) // 报错

# Enum

enum是枚举类型,类似过滤器

enum Hairline {
  'M',
  'line',
  'circle'
}

可通过值获取索引,也可通过索引获取对应的值(索引默认从0开始),也可自定义索引值

let hairline: Hairline = Hairline.M
console.log(hairline) // 0
console.log(Hairline.line, Hairline[2]) // 1 'circle'

// 自定义索引值
enum Hairline {
  'M' = 10,
  'line' = 21,
  'circle' = 2
}
let line: Hairline = Hairline.line
let circle: string = Hairline[2]
console.log(Hairline.M, line, circle) // 10 21 'circle'

# Any

开发阶段无法确定变量类型时,可以使用any类型来跳过编译阶段的类型检查

let unsure: any
unsure = 'Typescript'
unsure = 123
unsure = true
console.log(unsure)
// 
let list: any[] = ['Typescript', 123, true] 
console.log(list) // ['Typescript', 123, true]

# Void

void表示没有任何类型

声明一个void的变量似乎没有什么意义,只能被赋值为undefined,赋值为其他类型会报错

let nonsense: void = undefined
console.log(nonsense)

// 表示函数返回值只能为undefined,其他类型返回值会报错
function fn1(): void {
  console.log('fn1 void')
  // return undefined
  // return 123 // 报错
}

# Object

表示除boolean | number | string原始数据类型外的类型

  let obj: object = { name: 'Ethan' }
  console.log(obj)

  // 函数返回值必须为Object类型
  function fn2(): object {
    console.log('fn2 Object')
    return {}
  }

# Union Types

联合类型用来表示值的类型可以是定义中的其中一种

  let union: string | number
  union = 1
  union = '1'
  console.log(union)

❗️ 开发时应注意代码中是否会涉及到对值的处理,值类型的不同决定可用方法不同

  function fn3(val: string | number): number {
    // 报错:这里val如果为number类型,number类型是没有length属性可供调用的
    return val.length 
  }

这里改造下,做了对应不同类型的处理,但是还是有错误,就需要下面类型断言的知识点了

  function fn3(val: string|number): number {
    if (val.length) {
      return val.length
    } else {
      return val.toString().length
    }
  }

# 类型断言

类型断言就像是告诉编译器,不需要对此变量进行类型检查

类型断言好比其它语言里的类型转换,但是不进行特殊的数据检查和解构。 它没有运行时的影响,只是在编译阶段起作用。

两种方法实现:

  • <类型>值
  • 值 as 类型
  function fn3(val: string | number): number {
    // 方式一:
    if ((<string>val).length) {
      // 方式二:
      return (val as string).length
    } else {
      return val.toString().length
    }
  }

# 类型推断

在没有明确的指定类型的情况下,Typescript会推断一个类型作为该变量的数据类型

  // 定义变量时赋值,推断为对应的类型
  let val1 = 123 // number
  // val = '123' // string 报错

  // 定义变量时赋值,推断为any类型
  let val2 // any
  val2 = 123
  val2 = '123'