TypeScript 核心知识精要

一份结构化、重点突出的 TypeScript 学习笔记


一、类型系统基础

1.1 类型声明 vs 类型推断

类型声明:显式指定变量类型

typescript 复制代码
let a: string
let b: number
let c: boolean

function demo(x: number, y: number): number {
  return x + y
}

类型推断:TypeScript 自动推断类型

typescript 复制代码
let d = -99  // TS 推断为 number 类型
d = false    // ❌ 警告:不能将类型 "boolean" 分配给类型 "number"

核心要点

  • 类型声明更加明确,适合复杂类型和公共 API
  • 类型推断简化代码,适合局部变量和简单场景
  • 推荐优先使用类型推断,必要时显式声明

二、类型总览

2.1 TypeScript 新增类型

类型 含义 使用场景
any 任意类型,放弃类型检查 临时处理、迁移 JS 代码
unknown 类型安全的 any 接收外部数据、类型不确定时
never 永不存在的值 函数永不返回、穷尽检查
void 空或 undefined 函数无返回值
tuple 固定长度数组 坐标点、键值对
enum 枚举 固定选项集合

2.2 JavaScript 类型 vs TypeScript 类型

JS 原始类型stringnumberbooleannullundefinedbigintsymbolobject

TS 新增能力

  1. 所有 JS 类型
  2. 四个新类型:voidneverunknownanyenumtuple
  3. 自定义类型:typeinterface

三、常用类型详解

3.1 字面量类型

定义:值只能是特定的字面量

typescript 复制代码
let a: '你好'      // a 的值只能是字符串 "你好"
let b: 100        // b 的值只能是数字 100

// 联合字面量类型
let gender: '男' | '女'  // 值只能为 "男" 或 "女"

应用场景:限制变量为特定值集合,提高类型安全性


3.2 any 类型

特点:放弃类型检查,变量可以赋任何值

typescript 复制代码
let a: any
a = 100
a = '你好'
a = false
// 以上均无警告

// ⚠️ 危险:any 类型可以赋值给任意类型变量
let x: string
x = a  // 无警告,但运行时可能出错

使用建议

  • ❌ 避免滥用 any
  • ✅ 仅用于临时处理、迁移旧代码
  • ✅ 优先使用 unknown 替代

3.3 unknown 类型(⭐ 重点)

特点:类型安全的 any,必须类型缩小或断言后才能使用

typescript 复制代码
let a: unknown
a = 100
a = 'hello'

let x: string
x = a  // ❌ 警告:不能将类型 "unknown" 分配给类型 "string"

三种安全使用方式

typescript 复制代码
// 方式1:类型判断(推荐)
if (typeof a === 'string') {
  x = a  // ✅ 安全
}

// 方式2:类型断言 as
x = a as string

// 方式3:尖括号断言
x = <string>a

关键区别

typescript 复制代码
let str1: string = 'hello'
str1.toUpperCase()  // ✅ 无警告

let str2: any = 'hello'
str2.toUpperCase()  // ✅ 无警告(但不安全)

let str3: unknown = 'hello'
str3.toUpperCase()  // ❌ 警告:需要类型缩小或断言

(str3 as string).toUpperCase()  // ✅ 正确使用

3.4 never 类型

含义 :永不存在的值,连 undefinednull''0 都不行

使用场景1:函数永不返回

typescript 复制代码
function demo(): never {
  throw new Error('程序异常退出')
}

使用场景2:类型收窄的穷尽检查

typescript 复制代码
let a: string = 'hello'

if (typeof a === 'string') {
  a.toUpperCase()
} else {
  console.log(a)  // TS 推断此处 a 是 never,因为不可能执行
}

使用场景3:switch 穷尽检查

typescript 复制代码
enum Color { Red, Blue, Green }

function getColorName(c: Color): string {
  switch (c) {
    case Color.Red: return '红色'
    case Color.Blue: return '蓝色'
    case Color.Green: return '绿色'
    default:
      const exhaustiveCheck: never = c  // 如果新增颜色忘记处理,会报错
      return exhaustiveCheck
  }
}

3.5 void 类型

含义:空或 undefined,常用于函数返回值

typescript 复制代码
function demo1(): void { }                    // ✅ 无返回
function demo2(): void { return }             // ✅ 返回 undefined
function demo3(): void { return undefined }   // ✅ 显式返回 undefined
function demo4(): void { return 666 }         // ❌ 不能返回 number

3.6 object 与 Object

object:任何非原始值类型(对象、函数、数组等)

typescript 复制代码
let a: object
a = {}           // ✅
a = { name: '张三' }  // ✅
a = [1, 3, 5]    // ✅
a = function(){} // ✅
a = null         // ❌
a = 1            // ❌

Object:Object 的实例对象,范围太大,几乎不用

typescript 复制代码
let a: Object
a = 1       // ✅ 包装对象是 Object 实例
a = true    // ✅ 包装对象是 Object 实例
a = '你好'  // ✅ 包装对象是 Object 实例

实际开发推荐写法

typescript 复制代码
// 限制具体对象
let person: { name: string, age?: number }

// 允许可选属性和任意额外属性
let car: { price: number; color: string; [k: string]: any }

// 限制函数类型
let demo: (a: number, b: number) => number

// 限制数组类型
let arr1: string[]  // 等价于 Array<string>
let arr2: number[]  // 等价于 Array<number>

3.7 tuple(元组)

定义:固定长度、固定类型的数组

typescript 复制代码
let t: [string, number]
t = ['hello', 123]            // ✅
t = ['hello', 123, false]     // ❌ 长度不匹配

应用场景

  • 坐标点:[number, number]
  • 键值对:[string, any]
  • 函数返回多个值

3.8 enum(枚举)

定义:一组命名的常量集合

typescript 复制代码
enum Color {
  Red,     // 默认 0
  Blue,    // 默认 1
  Black,   // 默认 2
  Gold     // 默认 3
}

enum Color2 {
  Red = 6,   // 指定初始值
  Blue,      // 7(自动递增)
  Black,     // 8
  Gold       // 9
}

枚举编译结果

javascript 复制代码
// Color 编译后:
{
  0: 'Red',
  1: 'Blue',
  2: 'Black',
  3: 'Gold',
  Red: 0,
  Blue: 1,
  Black: 2,
  Gold: 3
}

实际应用

typescript 复制代码
let phone: { name: string, price: number, color: Color }

phone = {
  name: '华为Mate60',
  price: 6500,
  color: Color.Red
}

if (phone.color === Color.Red) {
  console.log('手机是红色的')
}

四、自定义类型

4.1 type(类型别名)

typescript 复制代码
enum Gender { Male, Female }

type Grade = 1 | 2 | 3  // 字面量联合类型

type Student = {
  name: string
  age: number
  gender: Gender
  grade: Grade
}

let s1: Student = {
  name: '张三',
  age: 18,
  gender: Gender.Male,
  grade: 1
}

五、抽象类

5.1 基本概念

抽象类特点

  • 不能实例化(不能 new)
  • 可以被继承
  • 可以包含抽象方法和普通方法
typescript 复制代码
abstract class Person {
  name: string
  age: number

  constructor(name: string, age: number) {
    this.name = name
    this.age = age
  }

  // 抽象方法:子类必须实现
  abstract speak(): void

  // 普通方法:子类可直接继承
  walk() {
    console.log('我在行走中....')
  }
}

class Teacher extends Person {
  constructor(name: string, age: number) {
    super(name, age)
  }

  speak() {
    console.log(`我是老师,我的名字是${this.name}`)
  }
}

// const p1 = new Person('周杰伦', 38)  // ❌ 抽象类不能实例化
const t1 = new Teacher('刘老师', 40)  // ✅

六、接口(Interface)

6.1 接口基础

定义:限制类、对象的结构

typescript 复制代码
interface Person {
  name: string
  age: number
  speak(): void
}

class Teacher implements Person {
  name: string
  age: number

  constructor(name: string, age: number) {
    this.name = name
    this.age = age
  }

  speak() {
    console.log(`你好!我是老师:`, this.name)
  }
}

6.2 接口可重复声明

typescript 复制代码
interface PersonInter {
  name: string
  age: number
}

interface PersonInter {
  speak(): void
}

// 等价于合并:
// interface PersonInter {
//   name: string
//   age: number
//   speak(): void
// }

6.3 接口 vs 类型别名

特性 接口 类型别名
用途 定义对象结构、类契约 定义任意类型
可扩展 ✅ 可重复声明合并 ❌ 不能重复声明
实现类 implements ❌ 不能实现
联合类型 ❌ 不支持 ✅ 支持
typescript 复制代码
// 接口可以当类型使用
let person: Person = {
  name: '张三',
  age: 18,
  speak() {
    console.log('你好!')
  }
}

// 类型别名只能当类型
type Grade = 1 | 2 | 3  // ✅
// interface Grade = 1 | 2 | 3  // ❌ 不支持

6.4 接口 vs 抽象类

特性 接口 抽象类
方法类型 只能有抽象方法 可有抽象方法和普通方法
实现方式 implements extends
多继承 ✅ 可实现多个接口 ❌ 单继承
默认实现 ❌ 无 ✅ 可有默认实现

七、属性修饰符

修饰符 含义 可访问范围
readonly 只读属性 任何地方都不能修改
public 公开 类、子类、对象均可访问
protected 受保护 类、子类可访问
private 私有 仅类内部可访问
typescript 复制代码
class Person {
  public name: string
  protected age: number
  private id: string
  readonly gender: '男' | '女'

  constructor(name: string, age: number, id: string) {
    this.name = name
    this.age = age
    this.id = id
    this.gender = '男'
  }
}

const p = new Person('张三', 18, '123')
p.name = '李四'      // ✅ public 可修改
p.age = 20          // ❌ protected 仅类和子类可访问
p.id = '456'        // ❌ private 仅类内部可访问
p.gender = '女'     // ❌ readonly 不可修改

八、泛型(Generics)

8.1 泛型基础

定义:定义函数或类时,类型不确定,使用类型变量表示

typescript 复制代码
function test<T>(arg: T): T {
  return arg
}

// 不指定类型,TS 自动推断
test(10)  // T 推断为 number

// 指定具体类型
test<number>(10)

8.2 多个泛型

typescript 复制代码
function test<T, K>(a: T, b: K): K {
  return b
}

test<number, string>(10, 'hello')

8.3 泛型类

typescript 复制代码
class MyClass<T> {
  prop: T

  constructor(prop: T) {
    this.prop = prop
  }
}

const instance = new MyClass<string>('hello')

8.4 泛型约束

限制泛型的范围

typescript 复制代码
interface Demo {
  length: number
}

// T 必须有 length 属性
function test<T extends Demo>(arg: T): number {
  return arg.length
}

test(10)                           // ❌ number 无 length
test({ name: '张三' })             // ❌ 无 length 属性
test('123')                        // ✅ string 有 length
test({ name: '张三', length: 10 }) // ✅

九、核心概念对比总结

9.1 any vs unknown

特性 any unknown
类型安全 ❌ 不安全 ✅ 类型安全
赋值给其他类型 ✅ 任意类型 ❌ 需要类型缩小
调用方法 ✅ 可调用 ❌ 需断言或类型缩小
推荐使用 ⚠️ 尽量避免 ✅ 推荐

9.2 type vs interface

优先使用 interface 的场景

  • 定义对象结构
  • 类需要实现的契约
  • 需要声明合并

优先使用 type 的场景

  • 联合类型、交叉类型
  • 元组、映射类型
  • 基本类型别名

十、学习要点与最佳实践

10.1 类型设计原则

  1. 优先使用具体类型,避免 any

    typescript 复制代码
    // ❌ 不好
    function process(data: any) { }
    
    // ✅ 更好
    function process(data: unknown) {
      if (typeof data === 'string') { }
    }
    
    // ✅ 最好
    function process(data: string | number) { }
  2. 善用类型推断,减少冗余声明

    typescript 复制代码
    // ❌ 冗余
    let a: number = 10
    const arr: number[] = [1, 2, 3]
    
    // ✅ 简洁
    let a = 10
    const arr = [1, 2, 3]
  3. 利用联合类型和字面量类型提高类型精度

    typescript 复制代码
    type Direction = 'up' | 'down' | 'left' | 'right'
    type Status = 'pending' | 'success' | 'error'

10.2 常见陷阱

  1. 混淆 Object 和 object

    • Object:几乎所有类型(包装对象)
    • object:非原始类型
  2. 误用 any 导致类型污染

    typescript 复制代码
    let a: any = 'hello'
    let b: string = a  // ❌ 类型污染,a 可能不是 string
  3. 忽略枚举的双向映射

    typescript 复制代码
    enum Color { Red = 0 }
    Color.Red      // 0
    Color[0]       // 'Red'(反向映射)

十一、快速复习清单

类型系统

  • 类型声明 vs 类型推断
  • JS 类型 + TS 新增类型
  • 字面量类型的使用

关键类型

  • any(放弃检查) vs unknown(类型安全)
  • never(永不返回) vs void(无返回值)
  • tuple(固定数组) vs enum(枚举)

高级特性

  • type(类型别名) vs interface(接口)
  • 抽象类(可实例化?) vs 接口(只能抽象方法?)
  • 属性修饰符:public、protected、private、readonly
  • 泛型:类型变量、泛型约束

设计原则

  • 优先具体类型,避免 any
  • 善用类型推断
  • 联合类型 + 字面量类型提高精度

相关推荐
dust_and_stars1 小时前
在Ubuntu 24.04上设置Jupyter Notebook远程访问
linux·ubuntu·jupyter
x_lrong1 小时前
Ubuntu下安装配置Claude Code
linux·ubuntu·elasticsearch
rising start1 小时前
五、Vue3 ref 用法 + Props 完整指南
前端·javascript·vue.js
web打印社区1 小时前
前端html转换pdf并静默打印pdf最佳实现路径
前端·javascript·vue.js·electron·html
济6171 小时前
ROS2 Humble 开发专栏---ROS2 三维视觉应用(1)---RGB-D 相机三维点云数据获取实验---适配Ubuntu 22.04
ubuntu·嵌入式·ros2·机器人开发·机器人方向
Curvatureflight2 小时前
浏览器音频采集实践:麦克风权限、降噪、回声消除与 PCM 转换
前端·javascript·音视频·信息与通信·web·pcm
刘国华-平价IT运维课堂2 小时前
Ubuntu 26.04 LTS 发布,研发与运维需要关注什么?
linux·运维·服务器·人工智能·ubuntu
云水一下11 小时前
TypeScript 从零基础到精通(五):高级类型与泛型
前端·javascript·typescript
云水一下11 小时前
TypeScript 从零基础到精通(六):类型声明与模块化
javascript·typescript