【问题标题】:Typescript merge interfaces from multiple files来自多个文件的打字稿合并接口
【发布时间】:2019-08-12 18:58:56
【问题描述】:

我有一个名为 service.ts 的文件,它公开了以下代码:

export interface SomeInterface {
  keyOne: string;
}

export class TestService<T = SomeInterface> {
  property: T;
}

index.ts 文件中我正在使用该服务:

import { TestService } from './service';

const service = new TestService();
service.property.keyOne

我还创建了index.d.ts 文件,该文件声明了相同的接口SomeInterface 具有更多键:

export interface SomeInterface {
  keyTwo: number;
}

问题是service.property 只“知道”keyOne 属性。如何告诉 typescript 合并它们?

https://stackblitz.com/edit/typescript-cp8zmv

【问题讨论】:

    标签: typescript


    【解决方案1】:

    如果我对您的理解正确(您在@chris p bacon 的回答中的评论),您想从库中扩充模块类型定义。 TypeScript 文档中指向declaration merging 的链接已经很好了。对于第三方库类型扩展,有一些很好的答案:herehere

    对于您的示例,如果我们出于某种原因想要扩充库模块类型定义(让我们说 vendor-lib.d.ts 而不是您的 index.d.ts 以使其更清晰),我们可以通过 Module Augmentation 做到这一点:

    供应商-lib.d.ts:

    export interface SomeInterface {
      keyTwo: number
    }
    

    service.ts

    // here for simplicity a relative import
    import { SomeInterface } from "./vendor-lib"
    
    // Augment above imported module. 
    // Important: this file must be a module (not a script) via `import/export`.
    // Then augmentation will work. Otherwise compiler expects a module declaration.
    declare module "./vendor-lib" {
      interface SomeInterface {
        keyOne: string
      }
    }
    

    index.ts:

    const service = new TestService(); service.property = {...};
    service.property.keyOne // works
    service.property.keyTwo // works
    

    StackBlitz

    【讨论】:

      【解决方案2】:

      你可以扩展接口并给它另一个名字

      export interface SomeInterface {
        keyOne: string;
      }
      
      export interface SomeExtendingInterface extends SomeInterface {
        keyTwo: number;
      }
      

      或者将它们合并为具有这两个属性的类型

      interface Foo {
          foo: string;
      }
      
      interface Bar {
          bar: string;
      }
      
      type Baz = Foo & Bar;
      
      const foo: Baz = {
          foo: '',
          bar: ''
      };
      

      【讨论】:

      • 它应该像我根据文档typescriptlang.org/docs/handbook/declaration-merging.html所做的那样工作
      • 不管它是否有效,为什么两个不同的接口必须具有相同的名称?在维护代码时,您不认为几个月后会感到困惑吗?但是做你喜欢的事......
      • 目的是让使用库的用户能够全局扩展接口。
      • @undefined 老实说,你应该在你的问题中添加它作为上下文,否则,它并没有多大意义。
      猜你喜欢
      • 1970-01-01
      • 2020-05-09
      • 2018-01-18
      • 2021-05-15
      • 1970-01-01
      • 2018-06-15
      • 1970-01-01
      • 2020-08-14
      • 2017-09-02
      相关资源
      最近更新 更多