Created
September 5, 2023 14:26
-
-
Save AlexVipond/299818a845dc8b4a6c901b22ab512e84 to your computer and use it in GitHub Desktop.
Automatic type inference for fetched data, using generics and `infer`
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
async function getPageData () { | |
const users = await get('/users') | |
const user1 = await get('/users/1') | |
const usersWithParams = await get('/users?limit=10') | |
const user1WithParams = await get('/users/1?hello=world') | |
return { | |
users, | |
user1, | |
usersWithParams, | |
user1WithParams, | |
} | |
} | |
async function get<Endpoint extends AnyEndpoint> ( | |
endpoint: Endpoint | |
): Promise<ResponseJson<Endpoint>> { | |
const response = await fetch(`/api${endpoint}`) | |
return await response.json() | |
} | |
type AnyEndpoint = `/${keyof ResponseJsonByEndpoint}/${number}?${string}` | |
| `/${keyof ResponseJsonByEndpoint}/${number}` | |
| `/${keyof ResponseJsonByEndpoint}?${string}` | |
| `/${keyof ResponseJsonByEndpoint}` | |
type ResponseJson<Endpoint extends AnyEndpoint> = | |
Endpoint extends `/${infer E extends keyof ResponseJsonByEndpoint}/${number}?${string}` | |
? ResponseJsonByEndpoint[E][number] | |
: Endpoint extends `/${infer E extends keyof ResponseJsonByEndpoint}/${number}` | |
? ResponseJsonByEndpoint[E][number] | |
: Endpoint extends `/${infer E extends keyof ResponseJsonByEndpoint}?${string}` | |
? ResponseJsonByEndpoint[E] | |
: Endpoint extends `/${infer E extends keyof ResponseJsonByEndpoint}` | |
? ResponseJsonByEndpoint[E] | |
: never | |
interface ResponseJsonByEndpoint { | |
'users': User[], | |
'tasks': Task[], | |
} | |
interface User { | |
id: number, | |
name: string, | |
password: 'password', | |
} | |
interface Task { | |
id: number, | |
name: string, | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment