#Accessing two levels deep into a type schema with generics not working?
17 messages · Page 1 of 1 (latest)
Preview:ts type APIEndpoints = { GET: { "/v1/foo/:id": { params: { ":id": string } response: { data?: { id: string } message: string errors?: any } ...
async function fetchM<Method extends keyof APIEndpoints, Path extends keyof APIEndpoints[keyof APIEndpoints]>(apiPath: Path, params: APIEndpoints[Method][Path]['params']): Promise<APIEndpoints[Method][Path]['response']>
might work for you?
this avoids typing the Path as keyof APIEndpoints[Method][string]
oh hmm i think that resolves (keyof APIEndpoints['GET'] & keyof APIEndpoints['POST'])
which is too narrow, like excludes the paths set
agh forgot to include the Method in my example, ideally I would be able to express it like this:
async function fetchM<Method extends keyof APIEndpoints, Path extends keyof APIEndpoints[Method]>(method: Method, apiPath: Path, params: APIEndpoints[Method][Path]['params']): Promise<APIEndpoints[Method][Path]['response']>
it's more brittle sadly
Preview:```ts
...
fetchGet('/v1/foo/:id/items', { ':id': '123' });
const ret = await fetchM("GET", "/v1/foo/:id/items", { ':id': ""});
// ^?```
the gist of the idea is: since typescript doesn't think those keys exist reliably, promise to it that they do exist and provide a fallback if they don't
according to my logic, it's impossible for those keys not to exist
but if they don't exist: you will get errors if you try to pass any params, and you'll receive Promise<unknown> as the output, which should swiftly lead to compile errors if you try to use it in any way
I found an alternative solution
declare function fetchM<
Method extends keyof APIEndpoints,
Path extends keyof Endpoints,
Endpoints extends { [key: string]: { params: {}, response: unknown } } = APIEndpoints[Method],
>(
method: Method,
apiPath: Path,
params: Endpoints[Path]['params']
): Promise<Endpoints[Path]['response']>
I don't prefer one over the other