Reputation: 1836
Because tsd
is deprecated, I'm trying to migrate an ambient declaration file on DefinitelyTyped
to the structure typings
encourages (external modules). Here's the typings repo I'm making for KeyboardJS and the GitHub issue that lead to this question.
KeyboardJS is pretty simple (3 classes, 2 interfaces, 1 instance) but creating a proper .d.ts
file for it has been troublesome for me. My requirements are simple:
The problem comes in with how KeyboardJS does its exports:
var Keyboard = require('./lib/keyboard');
var Locale = require('./lib/locale');
var KeyCombo = require('./lib/key-combo');
var keyboard = new Keyboard();
keyboard.setLocale('us', require('./locales/us'));
exports = module.exports = keyboard;
exports.Keyboard = Keyboard;
exports.Locale = Locale;
exports.KeyCombo = KeyCombo;
There are two other interfaces KeyboardJS has (but does not expose), KeyEvent
and EventHandler
:
interface KeyEvent extends KeyboardEvent {
preventRepeat(): void;
pressedKeys: string;
}
interface EventHandler {
(e?: KeyEvent): void;
}
So, the .d.ts
file needs to expose Keyboard
, Locale
, & KeyCombo
classes as well as default
(as an instance of Keyboard
) -- as an external module. I should be able to write TypeScript classes that extend the JavaScript classes. Also, I need to be able write functions having KeyEvent
and EventHandler
as parameters.
Is this possible with the current state of TypeScript or do I need to file a TypeScript bug to support this scenario? If it's possible, how would I go about writing the .d.ts
file?
Upvotes: 2
Views: 2821
Reputation: 2750
I created test.ts to hopefully simulate your library:
export class Keyboard {
hereiam() { }
}
export class Locale { }
export class KeyCombo { }
let out = new Keyboard();
export default out;
And the resulting d.ts:
export declare class Keyboard {
hereiam(): void;
}
export declare class Locale {
}
export declare class KeyCombo {
}
declare let out: Keyboard;
export default out;
And finally the way I was able to consume it:
import {default as l} from "./test";
l.hereiam();
So taking the definition a little further you can add the two interfaces:
declare module "lib" {
export interface KeyEvent extends KeyboardEvent {
preventRepeat(): void;
pressedKeys: string;
}
export interface EventHandler {
(e?: KeyEvent): void;
}
export class Keyboard {
hereiam(): void;
}
export class Locale {
}
export class KeyCombo {
}
let out: Keyboard;
export default out;
}
And then consume them like this:
import * as lib from "lib";
let l = lib.default;
l.hereiam();
let k = new lib.Keyboard();
k.hereiam();
var x: lib.EventHandler;
var y: lib.KeyEvent;
y.preventRepeat;
Upvotes: 1