Skip to content

Instantly share code, notes, and snippets.

@brandonkal
Created February 14, 2020 10:02
Show Gist options
  • Save brandonkal/853c3d1dc53a79d366b6662eaa84bb5f to your computer and use it in GitHub Desktop.
Save brandonkal/853c3d1dc53a79d366b6662eaa84bb5f to your computer and use it in GitHub Desktop.
Deno TypeScript fails with generics
#!/bin/sh
":" //; exec /usr/bin/env deno run --allow-run "$0" "$@"
.charAt(0);
// This example demonstrates how Deno fails with generics. Scroll down to line 54.
/**
* wait builds a promise that resolves after a certain time and a function to cancel the timer.
* @param sec the number of seconds to wait
* @param msg An object to return when the timer completes
* @param id An optional id to assign the setTimout to.
*/
export const wait = <T>(
sec: number,
msg?: T,
id?: any
): [Promise<T>, () => void] => {
function makeResolver(resolve: (arg: any) => void) {
//prettier-ignore
id = setTimeout(() => resolve(msg), sec * 1000)
}
return [new Promise((rs) => makeResolver(rs)), () => clearTimeout(id)]
}
/**
* withTimeout returns a new promise that resolves when the promise resolves or the timeout occurs.
* @param sec specify timeout in seconds
* @param promise a function that returns a promise. Be sure to call bind if it is a method.
* @param timoutMsg Specify an object to return if the timeout occurs
*/
export async function withTimeout<V, TO>(
sec: number,
promise: () => Promise<V>,
timoutMsg?: TO
): Promise<V | TO> {
const [waiting, cancel] = wait(sec, timoutMsg)
const result = await Promise.race([promise(), waiting])
cancel()
return result
}
const p = Deno.run({
args: ['sleep', '10'],
})
const toMsg: Deno.ProcessStatus = {
success: false,
signal: 255,
}
function isTimeoutMessage(x: any) {
return x.success === false && x.signal === 255
}
// Note that Deno TypeScript compiler does not correctly handly the generics.
// Standalone TypeScript can correctly see that typeof out == Deno.ProcessStatus
// Deno cannot.
// Deno should not behave differently here as it is confusing.
// Not that uncommenting the following line and adding <PS, PS> after withTimeout will compile.
// type PS = Deno.ProcessStatus
const out = await withTimeout(2, p.status.bind(p), toMsg)
if (!out.success) { // TS2339: Property 'success' does not exist on type 'unknown'
if (isTimeoutMessage(out)) {
console.error('Timout')
p.kill(6)
}
console.error(out.success)
}
console.log(out)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment