Reputation: 83376
I'm trying to add typings to a top-level module, basically I want
import DropDownButton from 'bootstrap-dropdown-button'
to be typed correctly. Inside of typings/bootstrap-dropdown-button/index.d.ts
I have the following
import {Component} from 'react';
declare module 'bootstrap-dropdown-button' {
//var DropdownButton: any;
//export default DropdownButton;
export default class DropdownButton extends Component<any, any> {}
}
which does not work. I get errors of
error TS2307: Cannot find module 'bootstrap-dropdown-button'.
But, if I remove the existing code and uncomment
var DropdownButton: any;
export default DropdownButton;
then everything works fine, though naturally my typings for this module are fairly weak.
It seems my typing does not work when I try to load up the Component
type from react. The react typings have been loaded via npm through @types/react
and work fine, otherwise.
How should I adjust my typing code so bootstrap-dropdown-button
is recognized by TypeScript, and interacts correctly with React.Component
.
Upvotes: 1
Views: 350
Reputation: 26883
In order to coexist peacefully both with ES module-style importing/exporting as well as ambient modules, TypeScript type definition files can be a little bit strange to follow, especially when cross-referencing them. Let's take a look at the type definitions in @types/react
to see what's going on:
export = React;
export as namespace React;
declare namespace React {
// a great many things, including:
interface Component<P, S> extends ComponentLifecycle<P, S> { }
class Component<P, S> {
// ...
}
}
What's basically going on here is that a TypeScript namespace is being defined with React's types, and the export
statements atop it indicate that the namespace's members should be used when referencing the react
package as an ES module.
The advantage to this method of declaring types is that both ambient and ES module situations are supported. The disadvantage is that it can be a little bit unclear about how to reference those types in some cases.
The key to remember here is that although React itself is exposed through an ES module (since you're import
ing it), its types can be referenced both via the module and via the namespace. But since you're trying to create a downstream type definition, you need to use the namespace because TypeScript doesn't treat type definition files like ES modules (though they specify types to be used with them).
declare module 'bootstrap-dropdown-button' {
export default class DropdownButton extends React.Component<any, any> {}
// ^^^^^^
}
In your type definition file, just qualify the external types you use with their namespace instead of trying to import them as a module.
Upvotes: 2