'What is the correct way to extend TypeScript definitions in a 3rd party library?

I'm using TypeScript 4.5.5

There's an interface DvaInstance in a 3rd party library dva, existing index.d.ts for this library looks sth. like:

export interface DvaInstance {
  // ...
}

export {
  connect, connectAdvanced, useSelector, useDispatch, useStore,
  DispatchProp, shallowEqual
} from 'react-redux';

A field named _store exists in JavaScript but is missing in this interface, and now I want to extend this interface to include this field.

So I went ahead and created a dva.d.ts:

declare module 'dva' {
  interface DvaInstance {
    _store: import('redux').Store;
  }
}

Then this field (_store) became available. However, tsc started to complain when I do import { connect } from 'dva':

Module '"dva"' has no exported member 'connect'.

Looks like my module declaration overrides dva's, and declaration merging is not working as I expected.

I searched online and a lot of articles (including official documentation) use import statement. So I tried again:

import { DvaInstance } from 'dva';

declare module 'dva' {
  interface DvaInstance {
    _store: import('redux').Store;
  }
}

This time, both import { connect } from 'dva' and _store field works, but tsc complains that 'DvaInstance' is already declared in the upper scope.

My questions are:

  • A top level import or export makes the .d.ts file a non-ambient module, how come the types in it are still available without explicitly importing it in other files (import 'dva.d.ts')?
  • What is the correct way to extend TypeScript definitions in a 3rd party library without unexpectedly overriding existing TypeScript definitions?


Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source