TypeScript基础类型详解:从基本类型到类型推断与断言

作者:闭包旅人时间:2026-10-24 20:34:41浏览:607

本文系统介绍TypeScript中的基础类型与对象类型,涵盖布尔、数字、字符串、Any、Void、Null、Undefined及Never类型。深入讲解数组与元组的定义及嵌套用法,解析类型推断机制(包括上下文类型与联合类型推断),并说明类型断言在JSX环境下的语法限制,帮助开发者掌握TS静态类型系统的核心概念。

TypeScript(TS)的静态类型体系在概念上可划分为两大类别:

第一类为基础类型,包括布尔值(boolean)、数字(number)、字符串(string)、任意类型(Any)、空类型(Void)、空值(Null)、未定义(Undefined)以及永不存在的类型(Never)。

第二类为对象类型,涵盖数组、函数、对象、枚举以及元组等复杂结构。

1. 基础类型详解

在 TypeScript 中,类型定义主要通过类型注解的方式实现,具体操作可参考以下示例代码。


;(function () {
  /*
   * 在 TS 中可以通过 let 变量名: 数据类型 = 变量值值得方式定义数据类型(类型注解)
   * 也可以在定义的时候不指定数据类型,TS 自身会推断该数据类型
   */
  // 布尔型
  let boo: boolean = false // 赋值非布尔值将会抛出异常

  // 数字类型
  let num: number = 100

  // 字符串
  let str: string = '字符串' // 使用单引号或者双引号定位
  str = `模板字符串` // 使用模板字符串定义

  // Any 类型 -> 表示该类型可以为动态的类型,该类型在编译的时候移除了类型检查
  let AnyType: any = 123
  AnyType = true // 重复赋值不会抛出异常

  // Void 类型 -> 通常用于没有返回值的函数类型
  function demo(): void {
    console.log('测试void类型')
  }
  demo()

  // 还有两个比较特殊的类型,就是 null 和 undefined
  // 这两个类型是所有类型的子类型,也就是说可以将这两个两个类型赋值给 number、string 等类型
  let u: undefined = undefined
  num = u // 将 number 类型的变量赋值为 undefined
  let n: null = null
  boo = n // 将 boolean 类型的变量赋值为 null
})()

基础类型相对简单,其概念与JavaScript高度相似,直观而言,TypeScript 相比JavaScript额外引入了类型定义机制。

此外,TypeScript 还引入了一种特殊的 Never 类型。该类型用于表示那些永远不会存在的值的类型。

例如,never 类型通常用作那些总是会抛出异常或根本不会有返回值的函数表达式或箭头函数的返回值类型。

2. 对象类型

2.1 数组类型

TypeScript 中的数组定义与 JavaScript 有所不同。在 TS 中,不仅可以将变量定义为数组,还可以明确指定数组内部元素的数据类型。

具体的数组定义示例代码如下所示:


;(function () {
  // 定义一个仅仅为数字的数组类型
  let arr1: number[] = [1, 2, 3]
  console.log(arr1)
  // 定义一个可以为 数字 字符串 布尔值的数组
  let arr2: (number | string | boolean)[] = ['1', '2', true]
  console.log(arr2)
  // 定义一个任意类型的数组
  let arr3 = [1, ['1', '2', true], true]
  console.log(arr3)

  // 定义个对象类型的数组,对象中必须有 name 和 age 两个属性
  const objectArray: { name: string; age: number }[] = [
    { name: '一碗周', age: 18 },
  ]
  // 或者通过 type alias 类型别名的方式声明
  // 通过 type 定义一个类型别名
  type User = { name: string; age: number }
  const objectArr: User[] = [{ name: '一碗周', age: 18 }]
})()

2.2 元组类型

元组类型允许表示一个已知元素数量和类型的数组,且数组中各元素的类型可以不相同。

元组类型的定义示例代码如下所示:


;(function () {
  // 定义一个值分别被 string 和 number 的元组
  let tuple: [string, number] = ['123', 123]
  console.log(tuple) // [ '123', 123 ]
  // 通过索引赋值
  tuple[0] = 'string'
  console.log(tuple) // [ 'string', 123 ]
  // 赋值其他类型
  // tuple[0] = true
  // console.log(tuple) // 抛出异常
})()

元组的主要作用在于严格约束数组中每一项的数据类型以及数组的总长度。

元组与数组支持相互嵌套,其语法结构如下所示:


// 元组和数组的嵌套
let tuples: [string, number][] = [
    ['123', 123],
    ['456', 456],
]

在上述代码中,[string, number] 表示一个具体的元组结构;若在其后增加 [],则定义为一个存放元组的数组。

2.3 对象类型

一个对象中可以包含上述所有类型,具体的对象定义示例代码如下所示:


;(function () {
  // 定义一个对象,里面包含 MyName 和 age 两个属性,其中 MyName 为 string 类型 age 为number 类型
  let obj: {
    MyName: string
    age: number
  }
  // 对象的赋值,如果不按上面指定的类型进行赋值会抛出异常
  obj = {
    MyName: '一碗周',
    age: 18,
  }
  console.log(obj) // { MyName: '一碗周', age: 18 }
})()

在 TypeScript 中,开发者并非必须在每个地方都显式标注类型,因为类型推断机制可以在不编写额外代码的情况下自动获取类型信息。不过,为了提升代码的可读性,建议显式写出每个变量的类型。

3. 类型推断机制

在 TypeScript 中,有时无需明确指定类型,编译器会根据赋值自动推断出合适的类型,如下面这段代码所示:


;(function () {
  let myName = '一碗周'
  myName = true // 错误:不能将类型“boolean”分配给类型“string”
})()

在定义 myName 变量时,并未指定其数据类型,仅赋予了一个字符串值。然而,若尝试将该值重新赋值为非 string 类型的值时,编译器将会抛出异常。

这就是 TypeScript(TypeScript)中最基础的类型推断逻辑,即根据等号右侧的值来推测左侧变量的数据类型。

3.1 类型联合中的类型推断

关于类型联合的详细信息,请参考联合类型、交叉类型和类型保护相关文档。

若一个变量可能具有多个类型的值,TypeScript(TypeScript )会将这些类型合并,组成一个联合类型。

联合类型推断的示例代码如下:


let arr = [1, '2'] // 定义一个包含字符串和数字的一个数组
// 为上面定义的数组重新赋值
// arr = [true, false] // 错误 不能将类型“boolean”分配给类型“string | number”

// 还有如下例子
let val = arr.length === 0 ? 0 : '数组长度不是0'
// val = false //  错误 不能将类型“boolean”分配给类型“string | number”


3.2 上下文类型推断

此前介绍的例子主要依据等号右侧的值来推断左侧类型。而上下文类型推断则不同,编译器会根据变量所处的上下文环境来推断其类型。

上下文类型推断的示例代码如下:


;(function () {
  // 定义一个接口
  interface Person {
    name: string
    age: number
  }
  // 通过上面定义的接口定义一个数组
  let arr: Person[] = [{ name: '一碗周', age: 18 }]
  // 遍历定义的数组
  arr.forEach(item => {
    // 根据当前所处的环境,编译器自动推断出 item 为 hobby 类型且不具有 hobby 属性
    console.log(item.hobby) // 类型“Person”上不存在属性“hobby”
  })
})()

在上述代码中,首先定义了一个 Person 接口,并用该接口定义一个数组。在遍历该数组时,编译器推断 item 为 Person 类型,因此若访问不存在的属性,编译器会抛出异常。

如果为函数表达式的参数添加显式的类型注解,上下文类型推断将被忽略,从而避免报错。

添加类型注解后的示例代码如下:


// 如果在上下文中明确类型信息,上下文将会被忽略。
arr.forEach((item: any) => {
    // 根据当前所处的环境,编译器自动推断出 item 为 hobby 类型且不具有 hobby 属性
    console.log(item.hobby) // 类型“Person”上不存在属性“hobby”
})

4. 类型断言

类型断言的作用是告知 TypeScript 编译器,某个值的数据类型即为指定类型,编译器无需再进行额外检查。

这种操作在运行时不会产生影响,仅在编译阶段起作用。

类型断言的示例代码如下:


let SomeValue: any = 'this is a string'
// 语法一
let StrLength1: number = (<string>SomeValue).length
// 语法二 as 语法
let StrLength2: number = (SomeValue as string).length

值得注意的是:在 TypeScript 中使用 JSX 语法时,仅支持第二种断言语法。

至此,关于 TypeScript 基础类型的介绍已完成。如需了解更多相关内容,请搜索本站历史文章或继续浏览后续文章,感谢大家的支持!

作者最新文章
相关文章
更多