interface

你可以在任何时候用interfaces取代types

  1. type Article = {
  2. title: string,
  3. price: number,
  4. vat: number,
  5. stock?: number,
  6. description?: string
  7. }
  8. interface ShopItem {
  9. title: string;
  10. price: number;
  11. vat: number;
  12. stock?: number;
  13. description?: string;
  14. }

Article和ShopItem具有相同的结构, interface各项间用分号隔开,也可以没有分号

如果使用class, types和interfaces都能被implemented

  1. class DVD implements ShopItem {
  2. title: string
  3. price: number
  4. vat: number
  5. constructor(title: string) {
  6. this.title = title
  7. this.price = 9.99
  8. this.vat = 0.2
  9. }
  10. }
  11. class Book implements Article {
  12. title: string
  13. price: number
  14. vat: number
  15. constructor(title: string) {
  16. this.title = title
  17. this.price = 39
  18. this.vat = 0.2
  19. }
  20. }

这里Book和DVD有相同的结构

Declaration Merging

interface和type最大的区别,是interface支持declaration merging
这意味着我们可以在同一个文件的不同位置声明同一个interface,TypeScript会把这些声明合并成一个
例如,在上述代码的基础上我们再加一段

  1. interface ShopItem {
  2. reviews: {
  3. rating: number,
  4. content: string
  5. }[]
  6. }

typescript会将刚开始声明的ShopItem和我们新增的合并
而使用了ShopItem接口的DVD类声明则会报错,因为缺少了新增的reviews属性
image.png

interface的这个特性适用于扩充全局interface,比如Window

  1. declare global {
  2. interface Window {
  3. isDevelopment: boolean
  4. }
  5. }

我们首先打开gloabl命名空间(namespace), namespace也可以被merge
然后打开Window接口,添加新的isDevelopment属性
然后我们就可以在任何地方使用window对象的这个新属性

  1. class Discount {
  2. ...
  3. apply(article: Article) {
  4. ...
  5. // Here we check if we are in dev mode
  6. if(window.isDevelopment) {
  7. console.log('Another discount applied')
  8. }
  9. }
  10. }