Reputation: 61716
Is it possible to simplify the declaration of resolve
variable in the TypeScript code below, without sacrificing type safety? I'm new to TypeScript, please bear with me.
The goal is to save the promise resolver callback, passed to to the executor function, so it can be invoked later outside it. What I've come up with is let resolve: ((v: number) => void) | null = null
. Try it in the TS Playground:
function timeout(ms: number): Promise<number> {
// save the promise's resolver to be invoked later
let resolve: ((v: number) => void) | null = null; // <===
const p = new Promise<number>(r => resolve = r);
const start = performance.now();
setTimeout(() => resolve!(performance.now() - start), ms);
return p;
}
If I don't make it a union type with null
, TypeScript will legitly complain that resolve
might be uninitialized when I invoke it later: setTimeout(() => resolve(...), ms)
. Is there a more concise way to do this, without introducing any
or TypeScript errors?
To clarify, the above example is a bit contrived, it could be easily simplified like this:
function timeout(ms: number): Promise<number> {
const start = performance.now();
return new Promise<number>(r =>
setTimeout(() => r(performance.now() - start)));
}
The question is however about TypeScript syntax. The actual code does need to save the promise's resolve
and reject
callbacks to implement the Deferred
pattern.
Upvotes: 1
Views: 212
Reputation: 370989
One way to make it more concise is to remove the null
s and not assign anything to resolve
at first:
function timeout(ms: number): Promise<number> {
let resolve: (v: number) => void;
const p = new Promise<number>(r => resolve = r);
const start = performance.now();
setTimeout(() => resolve(performance.now() - start), ms);
return p;
}
It may look a bit odd, but this does happen to work with any !
assertion.
If you happen to be able to return the Promise immediately, you could slim it down to
function timeout(ms: number) {
let resolve: (v: number) => void;
return new Promise<number>(r => {
resolve = r;
const start = performance.now();
setTimeout(() => resolve(performance.now() - start), ms);
});
}
Upvotes: 1