上一篇讲了类型标注,给变量和函数贴上类型。但真实项目里的数据结构往往更复杂:用户对象、接口返回值、几种可能的状态……这时就需要自己"定义类型"。TypeScript 提供了两个工具:interface 和 type。

interface:描述对象的形状

interface 就是一份"结构说明书",规定对象该有哪些字段、什么类型:

interface User {
  name: string;
  age: number;
  email?: string;        // ? 表示可选字段
}

const u1: User = { name: "小明", age: 18 };
const u2: User = { name: "小红", age: 20, email: "[email protected]" };

// 少写字段或类型不对,编辑器会直接标红
// const bad: User = { name: "小刚" };   // 报错:缺少 age

函数参数用上它,提示和检查就都有了:

function greet(user: User): string {
  return `你好,${user.name}!`;
}

console.log(greet({ name: "小明", age: 18 }));   // 输出:你好,小明!

interface 可以继承

用 extends 复用已有结构,避免重复定义:

interface Animal {
  name: string;
}

interface Dog extends Animal {
  breed: string;         // 狗狗多了个品种字段
}

const d: Dog = { name: "旺财", breed: "柴犬" };
console.log(`${d.name} 是一只 ${d.breed}`);   // 输出:旺财 是一只 柴犬

type:更灵活的类型别名

type 能给任意类型起名字,还能表达联合类型这种 interface 写不了的形状:

type ID = number | string;          // 联合类型:二选一

function show(id: ID): void {
  console.log(`编号:${id}`);
}

show(101);        // 输出:编号:101
show("A01");      // 输出:编号:A01

type Status = "loading" | "success" | "error";   // 字面量联合
const s: Status = "success";      // 只能是这三个字符串之一

type 同样能描述对象:

type Point = { x: number; y: number };
const p: Point = { x: 3, y: 5 };
console.log(p.x + p.y);           // 输出:8

该用哪个?

  • 描述对象、给类定契约 → 惯例用 interface,语义清楚,还能被 extends 继承
  • 联合类型、字面量类型、给基本类型起别名 → 只能用 type
  • 团队统一用其中一种也完全没问题,一致性比选择本身更重要

小结

  • interface 定义对象形状,支持 extends 继承,字段加 ? 表示可选
  • type 是类型别名,能写联合类型和字面量类型,覆盖面更广
  • 两者在描述对象时能力高度重叠,按团队规范选一种坚持用即可

有了这两个工具,就能把业务里的数据结构都翻译成类型,让编译器替你查错。