type Result = | { ok: true; value: T } | { ok: false; error: E }; function wrap any>(fn: T): (...args: Parameters) => Result> { return function(...args: Parameters): Result> { try { const value = fn(...args); return { ok: true, value, } } catch (error) { return { ok: false, error: error as Error, } } } } function wrapAsync Promise>(fn: T): (...args: Parameters) => Promise>> { return async function(...args: Parameters): Promise>> { try { const value = await fn(...args); return { ok: true, value, } } catch (error) { return { ok: false, error: error as Error, } } } } async function doSomethingAsync(arg: string) { return arg; } async function main() { // const result = wrap(JSON.parse)("asdf") // if (!result.ok) { // console.error("uh oh", result.error) // return; // } // console.log(result.value); const asyncResult = await wrapAsync(doSomethingAsync)('my arg') if (!asyncResult.ok) { console.error("uh oh async", result.error) return } console.log(asyncResult.value) } main()