4-1 TypeScript 基础 + 在 Vue 里加类型
TypeScript(TS)= JavaScript + 静态类型。对你这种后端同学是主场——你早就习惯类型了。本章帮你把已有的类型知识迁移到前端,并学会在 Vue 里给 props/emit/ref 标类型。很多 Vue 公司项目用 TS。
怎么练:TS 需要编译,不能双击 HTML 跑。最快的体验方式是在线 TypeScript Playground(
typescriptlang.org/play),粘代码即时看类型报错。工程里用 TS 见文末。
1. 为什么前端要 TS
JS 是动态类型,user.nmae(拼错)运行时才报错,而且是 undefined 静默出错。TS 在写代码时就标红提醒,还能自动补全。
后端类比:就是把 JS 从「弱类型脚本」变成你熟悉的「强类型语言」的开发体验——编译期查错、IDE 智能提示、重构安全。
2. 基础类型(你会秒懂)
let name: string = '张三'
let age: number = 30 // TS 不区分 int/float,都是 number
let active: boolean = true
let nothing: null = null
let ids: number[] = [1, 2, 3] // 数字数组
let names: string[] = ['a', 'b'] // 字符串数组
let tuple: [string, number] = ['张三', 30] // 元组:固定长度和类型
// 联合类型:可以是几种之一(很常用)
let status: 'loading' | 'success' | 'error' = 'loading'
let id: number | string = 1
// any:关闭类型检查(尽量少用,等于退回 JS)
let whatever: any = '随便'类型推断:能推断出来时可省略标注。const n = 1 TS 自动知道 n 是 number。
3. interface / type:定义对象结构(核心)
后端的 DTO / 实体类,在 TS 里用 interface 或 type 表达:
interface User {
id: number
name: string
email?: string // ? 表示可选
readonly token: string // readonly 只读
}
const u: User = { id: 1, name: '张三', token: 'abc' } // email 可不填
// type 也能干类似的事
type Status = 'on' | 'off'
type Point = { x: number; y: number }
interfacevstype:对象结构两者都行。经验:描述对象/可被继承扩展的用interface,联合类型/别名用type。初学不用纠结,挑一个用。
4. 函数类型
// 参数和返回值都标类型
function add(a: number, b: number): number {
return a + b
}
// 箭头函数
const greet = (name: string): string => `你好 ${name}`
// 可选参数 / 默认值
function log(msg: string, level?: string) {}
function pow(n: number, exp: number = 2): number { return n ** exp }
// 无返回值用 void
function print(msg: string): void { console.log(msg) }5. 泛型(后端有的话也很熟)
// T 是类型参数,调用时确定
function first<T>(arr: T[]): T {
return arr[0]
}
first<number>([1, 2, 3]) // 返回 number
first(['a', 'b']) // 自动推断 T = string
// 常见:接口返回的泛型包装
interface ApiResult<T> {
code: number
data: T
}
type UserResult = ApiResult<User> // data 就是 User这跟 Java 的
List<T>、C# 的泛型一个道理,直接迁移即可。
6. 在 Vue 里用 TS
工程里把 <script setup> 改成 <script setup lang="ts"> 就能写 TS。
给 ref 标类型
import { ref } from 'vue'
const count = ref(0) // 自动推断为 number,通常不用手动标
const name = ref<string>('') // 显式指定
const user = ref<User | null>(null) // 初始 null,之后会是 User —— 这种要显式标
const list = ref<User[]>([]) // 数组要标元素类型给 props 标类型(defineProps 泛型写法)
<script setup lang="ts">
interface Props {
title: string
count?: number // 可选
user: User
}
const props = defineProps<Props>()
// 带默认值用 withDefaults
// const props = withDefaults(defineProps<Props>(), { count: 0 })
</script>对比 JS 版的 defineProps({ title: { type: String } }),TS 版直接用 interface,更清晰、有提示。
给 emit 标类型
<script setup lang="ts">
const emit = defineEmits<{
(e: 'change', value: string): void
(e: 'submit', data: User): void
}>()
emit('change', '新值') // 类型不对会报错
</script>给接口返回标类型(配合 axios)
import request from './request'
interface User { id: number; name: string }
export function getUser(id: number) {
return request.get<User>(`/users/${id}`) // 返回类型带上 User
}调用处就能拿到带类型的数据,IDE 自动补全字段。
7. 在 Vite 项目里启用 TS
新建项目时选 TS 模板:
npm create vite@latest 项目名 -- --template vue-ts它会多出 tsconfig.json(TS 配置,像编译器设置),文件后缀用 .ts,组件里 <script setup lang="ts">。其余开发流程和第 2 部分完全一样。
已有 JS 项目想迁 TS 可以渐进式:TS 兼容 JS,可以一个文件一个文件地改。
8. 实用建议(别过度纠结类型)
- 初学别追求 100% 严谨,先把 string/number/boolean/数组/interface/联合类型用起来。
- 实在标不出来的,临时用
any顶住,跑通再优化(但别滥用)。 - 善用 IDE:把鼠标悬停在变量上,VS Code 会告诉你它的推断类型。
动手练习
- 打开在线 TS Playground,粘贴第 3 节的
Userinterface,故意漏写name字段,看报错。 - 写一个
add(a: number, b: number),调用时传个字符串,看 TS 报错。 - (有项目的话)把第 2 部分
vue-demo里某个组件改成lang="ts",给一个 ref 标上类型,体会提示。 - 给
api/user.js的getUser加一个User接口返回类型(需先把文件改成.ts)。
小结
- TS = JS + 静态类型,对后端是主场:编译期查错 + 智能提示。
- 基础:
string/number/boolean、数组、联合类型、interface/type、泛型。 - Vue 里:
<script setup lang="ts">,ref<T>()、defineProps<Props>()、defineEmits<{...}>()、request.get<T>()。 - 新项目用
--template vue-ts;别过度纠结,先用起来。
🎉 第 4 部分完成! ➡️ 最后 第 5 部分:实战项目,把所有知识串成一个真实的移动端商品小应用。