This is a follow-up question to this one.
Given the answer on that question, let's say I have the following ambient declaration file:
declare namespace Twilio {
interface IDevice {
ready(handler: Function): void;
}
let Device: IDevice;
}
This is working nicely on my application .ts
files, Twilio.Device.ready
is fully recognized. But I have my unit tests running with Jest and AFAIK, they run on a NodeJS environment.
As an over simplified mock on my tests I have this (which are .ts
files too):
global.Twilio = {
Device: {
ready: () => {},
offline: () => {},
error: () => {},
}
};
But this Twilio
instance is not recognized. I can fix that by adding something like below to a .d.ts
file:
declare global {
namespace NodeJS {
interface Global {
Twilio: any;
}
}
}
export = {}; // This is needed otherwise `declare global` won't work
However, I can't have this piece of code on the same file as the declare namespace Twilio
I first mentioned. They need to be on separate files, otherwise global.Twilio
on my tests will be recognized but Twilio.Device
on my code won't.
So my question is, how can I get both instances of Twilio
to be recognized in the app code and in the tests code?
And as a bonus question, it would be nice if I could use the Twilio
namespace declaration, somehow, as the type of the NodeJS Twilio
global instead of any
.
EDIT:
After a nice chat with Richard Seviora, discussing all my issues, I ended up with the following twilio.d.ts
file for my project:
/**
* Namespace declaration for the Twilio.js library global variable.
*/
declare namespace Twilio {
type DeviceCallback = (device : IDevice) => void;
type ConnectionCallback = (connection : IConnection) => void;
type ErrorCallback = (error : IError) => void;
interface IConnection {
parameters: IConnectionParameters;
}
interface IConnectionParameters {
From?: string;
To?: string;
}
interface IDevice {
cancel(handler: ConnectionCallback): void;
connect(params: IConnectionParameters): IConnection;
disconnect(handler: ConnectionCallback): void;
error(handler: ErrorCallback): void;
incoming(handler: ConnectionCallback): void;
offline(handler: DeviceCallback): void;
ready(handler: DeviceCallback): void;
setup(token: string, params: ISetupParameters): void;
}
interface IError {
message?: string;
code?: number;
connection?: IConnection;
}
interface ISetupParameters {
closeProtection: boolean;
}
let Device: IDevice;
}
/**
* Augment the Node.js namespace with a global declaration for the Twilio.js library.
*/
declare namespace NodeJS {
interface Global {
Twilio: {
// Partial type intended for test execution only!
Device: Partial<Twilio.IDevice>;
};
}
}
Hopefully others find this question and Richard's answer below insightful (since the declarations documentation is kinda lacking).
Thanks again Richard for all your assistance.