Reputation: 6884
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
Upvotes: 6
Views: 7943
Reputation: 74750
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
Upvotes: 13
Reputation: 73271
You'd extend the interface and give it another name
export interface SomeInterface {
keyOne: string;
}
export interface SomeExtendingInterface extends SomeInterface {
keyTwo: number;
}
Or merge them to a type that has both properties
interface Foo {
foo: string;
}
interface Bar {
bar: string;
}
type Baz = Foo & Bar;
const foo: Baz = {
foo: '',
bar: ''
};
Upvotes: 3