对象类型反复出现时,可以用 interface 或 type 为它命名。函数类型则约定输入和输出,让这些对象在代码中安全地传递。
用 interface 描述对象
1 2 3 4 5 6 7 8 9 10 11 12 13
| interface User { readonly id: number; name: string; nickname?: string; }
const user: User = { id: 1, name: "小明" }; user.name = "小林";
function displayName(user: User): string { return user.nickname ?? user.name; }
|
? 表示属性可以省略,读取时需要考虑 undefined。readonly 限制通过该类型修改属性,不会冻结对象,也不会让嵌套属性自动只读。
TypeScript 按结构判断兼容性:对象具备所需字段,就可以使用。但直接传入对象字面量时,会额外检查多余字段,帮助发现拼写错误。
interface 与 type 怎么选
type 也能描述对象,还能为联合类型、元组等起别名:
1 2 3
| type Status = "active" | "disabled"; type Point = [number, number]; type User = { id: number; name: string };
|
两者都适合描述普通对象,保持项目风格一致即可。需要联合类型时用 type;需要同名声明合并时用 interface,例如扩充第三方库的接口。
扩展对象结构的写法:
1 2 3 4 5 6 7 8 9 10
| interface User { id: number; name: string; }
interface Admin extends User { permissions: string[]; }
type UserRecord = User & { createdAt: string };
|
& 要求同时满足两边的类型,不是后面的字段覆盖前面的字段。比如 { id: number } & { id: string } 的 id 会变成 never。
参数与返回值
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| function greet(name: string, title?: string): string { return `你好,${title ?? ""}${name}`; }
function createPage(page = 1, pageSize = 20) { return { page, pageSize }; }
function sum(...values: number[]): number { return values.reduce((total, value) => total + value, 0); }
console.log(greet("小明")); console.log(createPage(undefined, 10)); console.log(sum(1, 2, 3));
|
- 可选参数用
?,通常放在必填参数之后。
- 默认值在省略参数或传入
undefined 时生效,null 不会触发默认值。
- 剩余参数用数组类型,返回值能清楚推断时可以省略标注。
函数类型与回调
1 2 3 4 5 6 7 8 9 10 11
| type Formatter = (value: number) => string; const formatPrice: Formatter = (value) => `¥${value.toFixed(2)}`;
function visit( names: string[], callback: (name: string, index: number) => void ): void { names.forEach(callback); }
visit(["小明", "小林"], (name) => console.log(name));
|
回调可以忽略不需要的参数,所以不必为了允许省略 index 而把它写成可选。index?: number 表示调用回调时可能不传索引,与这里的实际行为不同。
返回类型 void 表示调用者忽略结果,因此 (name) => names.push(name) 也可以用作返回 void 的回调,尽管 push 实际返回数字。
什么时候需要重载
输入不同、返回类型也随之变化时,可以用重载:
1 2 3 4 5 6 7 8 9 10
| function label(value: string): string; function label(value: string[]): string[]; function label(value: string | string[]): string | string[] { return typeof value === "string" ? `用户:${value}` : value.map((name) => `用户:${name}`); }
const one = label("小明"); const many = label(["小明", "小林"]);
|
前两行是公开签名,带函数体的是实现签名,不能单独作为重载调用。如果输入不同但返回类型相同,直接使用联合参数通常更简单。
上一篇:基础类型 · 下一篇:泛型与常用工具类型