Appearance
TypeScript 入门
本章管什么:为什么用 TS、基础类型与易混类型(
void/never/unknown)、any边界、接口与类型、Vue 里 props/emits 怎么写类型。定位是入门能讲清,不钻高级泛型体操。
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 类型别名的区别?各自使用场景?
interface | type | |
|---|---|---|
| 能描述 | 对象结构为主 | 任意类型:联合、交叉、元组等 |
| 合并 | 同名可声明合并 | 不能同名重复声明 |
| 继承 | 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 / 判别字段)收窄。
🎤 口述精简版
联合是「或者」,交叉是「并且」。状态枚举用联合,合并多个接口字段用交叉。