TypeScript 是一种为 JavaScript 增添静态类型的强语言,它通过类型定义提升了代码的可靠性和可维护性。在 TypeScript 的众多特性中,接口(interface)和类型(type)是两种定义数据结构的重要工具,它们在定义变量、对象或类的形态时各有所长。了解它们的异同和适用场景,可以帮助我们编写更清晰、更高效的代码。
接口(Interface)
接口是 TypeScript 早期版本中引入的特性,其设计灵感来源于面向对象编程(OOP)。接口允许我们定义对象的结构,并提供了一种创建可重用、可扩展对象类型的一流结构。
基本接口示例
interface Car {brand: string;color: string;
}
接口继承
接口的一个主要优势是继承能力。一个接口可以扩展其他接口,这使得在现有结构基础上构建新结构变得简单。
interface Person {name: string;
}interface User extends Person {age: number;
}const user: User = { name: 'Gerald', age: 30 };
用于类的接口
接口也是定义类的结构或“契约”的好选择,它规定了类应具有的方法和属性。
interface Printable {print: () => void;
}class Cart implements Printable {print() {console.log('Item has been added.');}
}
接口声明合并
接口可以进行声明合并——如果在相同作用域内声明了多个同名接口,它们将合并为一个。这个特性有时很有用,但过度使用可能会导致接口难以理解和调试。
interface User {name: string;
}interface User {age: number;
}const user: User = { name: 'Gerald', age: 30 };
「注意:」
谨慎使用声明合并。过度合并可能会因为意外的副作用而导致接口难以理解和调试。
类型(Type)
可以定义联合类型、交叉类
使用type定义联合类型
例如,type允许定义联合类型,这是接口无法做到的。
type Id = string | number;
type声明的限制
与接口不同,type不支持声明合并。尝试重新声明一个type会导致错误。
type User = {name: string;
};// 错误:重复的标识符 'User'
type User = {age: number;
};
type类型组合
type也非常适合从现有类型中组合出新的类型,使其成为定义复杂数据结构的强大工具。
type User = {name: string;age: number;address: string;
};type PartialUser = Partial<User>;
const partialUser: PartialUser = {name: 'Gerald',age: 30,
};type NameOnly = Pick<User, 'name'>;
const nameOnly: NameOnly = {name: 'Gerald',
};
何时使用每种类型
- 在定义对象和类的结构时使用接口,因为它们在继承方面提供了更好的灵活性,并且与 TypeScript 的类型检查无缝配合。
- 使用type来处理联合类型、交叉类型、原始类型别名,或者当您需要创建复杂的、可重用的类型时。
结论
接口和type都为 TypeScript 带来了宝贵的功能。通过了解它们各自的优势,您可以为每种情况选择正确的工具,使您的代码更清晰、更易理解和更易于维护。拥抱 TypeScript 类型系统的强大功能,并享受它为您的项目带来的清晰性和安全性!