My issue arises from attempting to add a TypeScript type definition .d.ts
to a 3rd party library. Keep in mind I do not control this library, I am simply trying to consume it and appease the tsc compiler.
Reading the guidelines here re: writing d.ts
files:
https://typescript.codeplex.com/wikipage?title=Writing%20Definition%20%28.d.ts%29%20Files
I am looking at this specific example: New + callable methods
Here, the documentation shows the following pattern:
interface Widget {
sprock(): void;
}
interface WidgetFactory {
new(name: string): Widget;
(width: number, height: number): Widget;
}
declare var widget: WidgetFactory;
Building on this I have created the following for my needs:
declare module "react-localization" {
interface LocalizedStringsMethods {
setLanguage(language: string): void;
getLanguage(): string;
getInterfaceLanguage(): string;
formatString(str: string, ...values: any[]): string
getAvailableLanguages(): string[]
}
interface LocalizedStringsFactory {
new (props: any): LocalizedStringsMethods;
}
var LocalizedStrings: LocalizedStringsFactory;
export default LocalizedStrings;
}
The notable exception here is the documentation version does not use declare module
. Aside from that, to my eye, these SHOULD be the same an yield a similar result; I am clearly missing something. I get the following error instead:
error TS2351: Cannot use 'new' with an expression whose type lacks a call or construct signature.
I can change my definition to this:
declare module "react-localization" {
var LocalizedStrings: any;
export = LocalizedStrings;
}
The error is now gone, but I lose all the wonderful type information. =,(
I am at a loss. What exactly am doing wrong here?
Ok to add to the mystery, I tried doing export =
in the fuller type example instead of export default
:
declare module "react-localization" {
interface LocalizedStringsMethods {
setLanguage(language: string): void;
getLanguage(): string;
getInterfaceLanguage(): string;
formatString(str: string, ...values: any[]): string
getAvailableLanguages(): string[]
}
interface LocalizedStringsFactory {
new (props: any): LocalizedStringsMethods;
}
var LocalizedStrings: LocalizedStringsFactory;
export = LocalizedStrings; // <----- HERE instead of export default
}
Can someone explain to me why this works but export default
ends up returning undefined
? Also, I have to import this like:
import * as LocalizedStrings from 'react-localization'
I'd prefer to do the import as import LocalizedStrings from 'react-localization
. At this point I'll live with the former, I'd just like to understand why.
When Babel transpiles a module whose only export is an export default it injects a module.exports = exports["default"]; into the generated code, causing the exported object to become the function itself (instead of a module object that has the function as the default property).
– AJ Venturella