interface 和 type到底有什么区别

214 阅读3分钟

主要区别

  1. 定义范围:

    • interface 主要用于定义对象类型,可以描述类、对象字面量等。
    • type 可以定义任意类型的别名,包括基本类型、数组、元组、枚举、联合类型、交叉类型等。
  2. 扩展性:

    • interface 支持合并,可以用来扩展其他接口,这对于分步定义复杂的类型非常有用。
    • type 不支持合并,因此不能将两个类型别名合并在一起。
  3. 重用性:

    • interface 可以被多次扩展,这使得它非常适合用来构建可组合的类型系统。
    • type 也可以被重用,但是没有 interface 的合并机制,所以对于复杂类型可能需要重新定义整个类型。
  4. 编译行为:

    • interface 被视为开放集合,也就是说,在其他地方可以扩展相同的接口,即使是在不同的文件中。
    • type 则被视为封闭集合,不能被其他地方定义的相同名称的类型别名自动合并。
  5. 互操作性:

    • 当使用 interface 时,可以更容易地保证类型的一致性和兼容性。
    • 使用 type 定义的类型,在进行类型扩展或修改时需要更加小心,以确保类型的安全性。

面试中总询问的原因

  • 理解候选人的基础知识:这个问题可以帮助面试官了解候选人对 TypeScript 基础知识的理解程度。
  • 评估问题解决能力:通过讨论 interface 和 type 的使用场景,可以考察候选人如何根据实际情况选择合适的数据类型定义方式。
  • 考察设计模式和架构思维:在实际项目中,合理地使用 interface 和 type 可以帮助提高代码的可维护性和可读性,面试官可以通过这个问题来了解候选人在这方面的思考。

现在让我们通过具体的例子来说明 interface 和 type 在 TypeScript 中的不同之处。

案例对比(实践是检验真理的唯一标准)

1. 定义范围

interface 示例
interface Person {
    name: string;
    age: number;
}

// 可以直接使用
let person: Person = { name: "Alice", age: 30 };
type 示例
type NameAgeTuple = [string, number];

// 使用元组类型
let nameAge: NameAgeTuple = ["Alice", 30];

2. 扩展性

interface 示例
interface Person {
    name: string;
    age: number;
}

// 扩展接口
interface Developer extends Person {
    skills: string[];
}

let dev: Developer = { name: "Bob", age: 28, skills: ["TypeScript", "React"] };
type 示例
type Person = {
    name: string;
    age: number;
};

// 不能合并类型别名
type Developer = Person & {
    skills: string[];
};

let dev: Developer = { name: "Bob", age: 28, skills: ["TypeScript", "React"] };

3. 重用性

interface 示例
interface Person {
    name: string;
    age: number;
}

interface Developer extends Person {
    skills: string[];
}

interface Teacher extends Person {
    subject: string;
}
type 示例
type Person = {
    name: string;
    age: number;
};

// 重用类型别名
type Developer = Person & {
    skills: string[];
};

type Teacher = Person & {
    subject: string;
}

4. 编译行为

interface 示例
// 文件1
interface Animal {
    name: string;
}

// 文件2
interface Animal {
    sound: string;
}

// 合并后的Animal接口
let animal: Animal = { name: "Cat", sound: "Meow" };
type 示例
// 文件1
type Animal = {
    name: string;
};

// 文件2
type Animal = {
    sound: string;
};

// 编译错误,因为类型别名不能合并
let animal: Animal = { name: "Cat", sound: "Meow" };

5. 互操作性

interface 示例
interface Animal {
    name: string;
    sound: string;
}

// 实现接口
class Dog implements Animal {
    name: string;
    sound: string;

    constructor(name: string, sound: string) {
        this.name = name;
        this.sound = sound;
    }
}
type 示例
type Animal = {
    name: string;
    sound: string;
};

// 类型别名不能被类实现
class Dog {
    name: string;
    sound: string;

    constructor(name: string, sound: string) {
        this.name = name;
        this.sound = sound;
    }
}

通过这些例子,我们可以看到 interface 和 type 在使用上的差异。interface 更适合定义对象结构,支持合并和扩展,而 type 则更适合定义复杂类型,如元组、联合类型等,并且在定义时更加灵活。面试官询问这些问题是为了评估候选人是否能够根据实际需求选择合适的工具来解决问题。