问题
I'm using Twilio.js library on my application (not Twilio Node) and there's no module nor typings for this library available. There's only a Twilio
global variable available that one can use.
The simplest ambient declaration one can have to avoid errors in the IDE is this:
declare const Twilio: any;
But I want to go a little bit further and for that I've been reading TypeScript handbook and few other resources. I've taken especially attention to this link.
And here's what I have so far:
declare const Twilio: Twilio.Base;
declare namespace Twilio {
export interface Base {
Device: Device;
}
export interface Device {
ready(handler: DeviceCallback): void;
}
export interface DeviceCallback {
(device: Device): void;
}
}
This is working, but it's just a sample, it's not complete. As an example, it suffices for now :)
But my question is three-fold:
- Given the short sample above, would you do anything differently?
- If I remove the
export
keyword from all interfaces, it still works. Should I still leave it? What does it do? Given the usage
Twilio.Device.ready(this.handleTwilioDeviceReady.bind(this));
, IDEs give me the following when hovering my mouse over:Twilio
:const Twilio: Twilio.Base
Twilio.Device
:(property) Twilio.Base.Device: Twilio.Device
Twilio.Device.ready
:(method) Twilio.Device.ready(handler: Twilio.DeviceCallback): void
How can I get rid of
Twilio.Base
showing up in the IDE and instead show:Twilio
:const Twilio: Twilio
Twilio.Device
:(property) Twilio.Device: Twilio.Device
回答1:
I've taken a look at the API and I think the below should be a good starting point as an ambient declaration file.
declare namespace Twilio {
class Connection {
// Constructor does not appear to be available to user.
private constructor();
// Add Connection Methods and Properties Here
}
// Not immediately clear if Twilio.Device is a class or not.
interface IDevice {
setup(token, options);
ready(handler);
offline(handler);
incoming(handler);
connect(params) : Connection;
// Add Remainder of Twilio.Device properties here.
}
/**
* Twilio.Device appears to be a singleton object that
* you don't instantiate yourself. You can use
* the below to declare its presence.
*/
let Device : IDevice;
}
A few more notes:
declare const Twilio: Twilio.Base;
This is made redundant by the following namespace declaration, which has the effect of declaring the presence of a plain old JS object with the name and members you've declared.
Export doesn't appear to have any function when declaring ambient classes/namespaces. It's only necessary if you're declaring a module with a default export member, or if you're writing a TS file and need to declare which classes and interfaces will be publicly accessible.
EDIT : Callback Type for Device.Ready
IDevice
has the ready
method, which accepts an function argument that's passed an IDevice
object, and isn't expected to return anything. The type signature for such a function is:
(device : IDevice) => void;
An inline declaration would be:
ready((device : IDevice) => void) : void;
Given that you're going to reuse this callback type a few times, you should create a type alias and then refer to it like so:
type DeviceCallback = (device : IDevice) => void;
interface IDevice {
...
ready(handler: DeviceCallback) : void;
offline(handler : DeviceCallback) : void;
...
}
来源:https://stackoverflow.com/questions/42317942/how-to-create-ambient-declarations-for-twilio-global-js-library-in-typescript