Created
August 23, 2022 01:14
-
-
Save jonathantneal/a9b9eaf6889038cf5d9841aedaba99ca to your computer and use it in GitHub Desktop.
Fetch JSON returns the result with narrow typing
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
// @ts-check | |
import * as fs from 'node:fs' | |
/** Fetches JSON returns the result with narrow typing. */ | |
export let fetchJSON = /** @type {(input: RequestInfo | URL, init?: RequestInit) => any} */ ( | |
async (/** @type {string} */ input, config = any) => { | |
const response = await fetch(input, config) | |
const responseJSON = await response.json() | |
typedHash[input] = JSON.stringify(responseJSON) | |
setTyping() | |
return responseJSON | |
} | |
) | |
/** Path to the typing for this script. */ | |
const typedPath = new URL('./fetchJSON.d.ts', import.meta.url) | |
/** Text used to populate the typing for this script. */ | |
const typedText = `type JFetch<T> = (\n\tPromise<any>\n)\n\nexport declare function fetchJSON<T extends string>(resource: T): JFetch<T>` | |
/** Hashmap used to store typing results. */ | |
const typedHash = /** @type {Record<string, string>} */ (Object.create(null)) | |
/** Updates the typing file. */ | |
const setTyping = () => fs.writeFileSync(typedPath, typedText.slice(0, 20) + Object.entries(typedHash).reduce( | |
(list, [ input, responseJSON ]) => list + `T extends "${input}" ? Promise<${responseJSON}> :\n\t`, | |
'' | |
) + typedText.slice(20)) | |
const any = /** @type {any} */ (null) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment