-
-
Save brandonkal/853c3d1dc53a79d366b6662eaa84bb5f to your computer and use it in GitHub Desktop.
Deno TypeScript fails with generics
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/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