Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Typescript merge interfaces from multiple files

Tags:

typescript

I have a file named service.ts which exposes the following code:

export interface SomeInterface {
  keyOne: string;
}

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

In index.ts file I am using the service:

import { TestService } from './service';

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

I also created index.d.ts file which declare the same interface SomeInterface with more keys:

export interface SomeInterface {
  keyTwo: number;
}

The problem is that service.property only "knows" the keyOne property. How can I tell typescript to merge both of them?

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

like image 661
undefined Avatar asked Aug 11 '19 20:08

undefined


People also ask

How to merge two interfaces TypeScript?

To merge two interfaces with TypeScript, we can use extends to extend multiple interfaces. to create the IFooBar that extends IFoo and IBar . This means IFooBar has all the members from both interfaces inside.

How to export multiple interfaces in TypeScript?

Use named exports to export multiple interfaces in TypeScript, e.g. export interface A {} and export interface B {} . The exported interfaces can be imported by using a named import as import {A, B} from './another-file' . You can have as many named exports as necessary in a single file.

What is declaration merging in TypeScript?

For the purposes of this article, “declaration merging” means that the compiler merges two separate declarations declared with the same name into a single definition. This merged definition has the features of both of the original declarations.

Can TypeScript implement multiple interfaces?

Typescript allows an interface to inherit from multiple interfaces.


1 Answers

If I understand you correctly (your comment in @chris p bacon's answer), you want to augment a module type definition from a library. The link to declaration merging in TypeScript docs is already a good catch. There are some good answers out there dealing with third party lib type extensions: here and here.

For your example, if we want to augment a library module type definition for some reason (let's say vendor-lib.d.ts instead of your index.d.ts to make it clearer), we can do that via Module Augmentation:

vendor-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

like image 169
ford04 Avatar answered Oct 22 '22 10:10

ford04