Skip to content

TypeScript 入门 ​

本章管什么:为什么用 TS、基础类型与易混类型(void / never / unknown)、any 边界、接口与类型、Vue 里 props/emits 怎么写类型。定位是入门能讲清,不钻高级泛型体操。

本章不管什么:框架怎么选 → 架构;构建链路里 Babel/打包 → 构建 / 工程化。

TS 相比 JS 的优势是什么?项目中为什么要用 TS? ​

优势 ​

  • 类型约束:编译期就能发现很多低级错误(拼错字段、传错参数)
  • 更好的提示:IDE 自动补全、重构更安全
  • 可读可维护:接口、类型把数据结构写清楚,协作成本低
  • 渐进采用:可以和 JS 混用,慢慢迁

项目为什么用 ​

团队协作、业务对象多、重构频繁时收益最大;不是「必须」,而是用类型换长期可维护性。

🎤 口述精简版 ​

TS 在 JS 上加了静态类型,写的时候就能拦住一批错误,提示和重构也更稳。项目里用它主要是为了协作和可维护,尤其接口字段多、人多的时候。

TS 基础数据类型有哪些?null、undefined、void、never、unknown 的区别? ​

常见基础类型 ​

string / number / boolean / null / undefined / symbol / bigint,以及数组、元组、对象、枚举等。

几个易混类型 ​

类型含义备注
null空值常表示「有意没有」
undefined未定义变量声明未赋值、缺属性
void无返回值函数不 return,或 return 无意义
never永远不会有值抛错、死循环、穷尽检查
unknown未知类型类型安全的 any:用前必须收窄

🎤 口述精简版 ​

基础类型和 JS 差不多, 常问这几个:void 表示没返回值;never 表示走不到尽头;unknown 是安全的未知类型,用之前要收窄;null/undefined 一个是空、一个是没赋值。

any 的弊端?什么场景可以谨慎使用 any? ​

弊端 ​

  • 关掉类型检查,等于退回 JS
  • 错误会拖到运行时才爆
  • 传染:一个 any 会让相关推导都变糊

可谨慎使用的场景 ​

  • 真正说不清的第三方烂类型、临时桥接
  • 快速打样,但计划尽快补类型
  • 优先考虑 unknown + 类型收窄,而不是一上来 any

🎤 口述精简版 ​

any 会放弃类型保护,还能传染。实在没办法才用,比如第三方类型很烂的时候;能用 unknown 就别用 any。

interface 接口和 type 类型别名的区别?各自使用场景? ​

interfacetype
能描述对象结构为主任意类型:联合、交叉、元组等
合并同名可声明合并不能同名重复声明
继承extends交叉类型 &
表达力对象场景很合适联合类型、映射类型更灵活

使用建议 ​

  • 对象、可扩展的公共契约 → 偏 interface
  • 联合类型、工具类型、复杂组合 → 用 type
  • 团队统一一套即可,别混得太乱

🎤 口述精简版 ​

interface 适合描述对象,还能同名合并;type 更全能,联合、交叉都能写。对象用 interface,联合类型用 type,是常见分法。

什么是泛型?泛型的作用和基础使用方式? ​

泛型:类型里的「参数」,调用时再传入具体类型,实现复用 + 保持类型信息。

ts
function identity<T>(value: T): T {
  return value
}
identity<string>('hi')

常见:Array<T>、请求封装 request<T>()、组件 props 泛型。

🎤 口述精简版 ​

泛型就是类型参数,函数或接口先占位,用的时候再填具体类型,既复用又不丢类型。

TS 类型断言的使用场景和写法? ​

你比编译器更清楚类型时,用断言「告诉它按这个类型看」。

ts
const el = document.querySelector('#app') as HTMLDivElement
const val = someValue as string
// 或
const val2 = <string>someValue // JSX 里少用这种

场景:DOM 类型收窄、JSON 解析后的结构、字面量收窄。

注意:断言不会运行时转换,乱断言会埋雷;优先用类型守卫。

🎤 口述精简版 ​

断言是开发者告诉 TS「就按这个类型」。写法常用 as。它不改变运行时,只影响编译检查,别滥用。

Vue3 中如何用 TS 定义 props、emits? ​

ts
const props = defineProps<{
  title: string
  count?: number
}>()

const emit = defineEmits<{
  change: [id: number]
  close: []
}>()

也可用运行时写法 + 泛型辅助;复杂对象可抽成 interface / type。

🎤 口述精简版 ​

<script setup lang="ts"> 里用 defineProps<{}>()、defineEmits<{}>() 给 props 和事件加类型,对象结构可以抽成 interface。

TS 可选属性、只读属性如何定义? ​

ts
interface User {
  id: number
  name?: string      // 可选
  readonly token: string // 只读,创建后不能改
}

Partial<T> 全变可选;Readonly<T> 全变只读。

🎤 口述精简版 ​

可选加 ?,只读加 readonly。批量改可用 Partial、Readonly 工具类型。

联合类型、交叉类型的区别和使用场景? ​

联合 A | B交叉 A & B
含义要么 A 要么 B同时满足 A 和 B
场景状态、多种返回可能合并多个对象类型
ts
type Status = 'loading' | 'success' | 'error' // 联合
type Admin = User & { role: 'admin' }         // 交叉

联合常用类型守卫(typeof / in / 判别字段)收窄。

🎤 口述精简版 ​

联合是「或者」,交叉是「并且」。状态枚举用联合,合并多个接口字段用交叉。