面试题答案
一键面试主要区别
- 定义方式
- type:使用
type
关键字定义,例如type UserType = { name: string; age: number; };
- interface:使用
interface
关键字定义,例如interface UserInterface { name: string; age: number; }
- type:使用
- 类型覆盖与合并
- type:不支持合并,如果定义相同名称的
type
会报错。例如:
type UserType = { name: string; }; type UserType = { age: number; }; // 报错,重复定义
- interface:支持同名接口合并,将属性合并在一起。例如:
interface UserInterface { name: string; } interface UserInterface { age: number; } // 合并后UserInterface为 { name: string; age: number; }
- type:不支持合并,如果定义相同名称的
- 类型别名可用于原始类型、联合类型和元组类型
- type:可以为原始类型创建别名,如
type StringAlias = string;
,也能定义联合类型别名type StringOrNumber = string | number;
,还能定义元组类型别名type MyTuple = [string, number];
- interface:不能用于原始类型、联合类型和元组类型定义。
- type:可以为原始类型创建别名,如
- 实现与扩展
- type:通过交叉类型
&
实现类似接口扩展功能,例如type AdminType = UserType & { role: string; };
- interface:使用
extends
关键字扩展,例如interface AdminInterface extends UserInterface { role: string; }
- type:通过交叉类型
适用场景
- 适合使用 type 的场景
- 联合类型和交叉类型:当需要定义联合类型或交叉类型时,
type
更合适。例如,一个函数可以接收字符串或数字类型参数:
type StringOrNumber = string | number; function printValue(value: StringOrNumber) { console.log(value); }
- 原始类型别名:为原始类型创建更具描述性的别名,如在处理特定字符串类型时。
type Email = string; function sendEmail(to: Email, message: string) { console.log(`Sending email to ${to}: ${message}`); }
- 联合类型和交叉类型:当需要定义联合类型或交叉类型时,
- 适合使用 interface 的场景
- 对象类型定义且可能需要合并:如果定义对象类型,并且后续可能会有其他部分添加相同接口的属性,
interface
的合并特性很有用。例如,在模块化开发中不同模块对用户信息的扩展。
interface User { name: string; } interface User { age: number; } let user: User = { name: 'John', age: 30 };
- 实现接口(implements):当一个类需要实现某个类型定义时,
interface
更符合习惯。例如:
interface Shape { area(): number; } class Circle implements Shape { constructor(public radius: number) {} area(): number { return Math.PI * this.radius * this.radius; } }
- 对象类型定义且可能需要合并:如果定义对象类型,并且后续可能会有其他部分添加相同接口的属性,