From a1f2dd78465c1f6e5f1f7f928b025978dd094e25 Mon Sep 17 00:00:00 2001 From: syuilo Date: Mon, 31 May 2021 23:00:48 +0900 Subject: [PATCH] Improve type --- src/api.ts | 17 +++++++++++++---- src/endpoints.ts | 13 +++++++++++-- 2 files changed, 24 insertions(+), 6 deletions(-) diff --git a/src/api.ts b/src/api.ts index 1e622d3725..8961fb7ba0 100644 --- a/src/api.ts +++ b/src/api.ts @@ -24,6 +24,10 @@ export type FetchLike = (input: string, init?: { json(): Promise; }>; +type IsNeverType = [T] extends [never] ? true : false; + +type StrictExtract = Cond extends Union ? Union : never; + export class APIClient { public origin: string; public credential: string | null | undefined; @@ -39,14 +43,19 @@ export class APIClient { this.fetch = opts.fetch || fetch; } - public request( - endpoint: E, data: Endpoints[E]['req'] = {}, credential?: string | null | undefined, - ): Promise { + public request( + endpoint: E, params: P, credential?: string | null | undefined, + ): Promise> extends true + ? Endpoints[E]['res']['$switch']['$default'] + : StrictExtract[1] + : Endpoints[E]['res']> + { const promise = new Promise((resolve, reject) => { this.fetch(`${this.origin}/api/${endpoint}`, { method: 'POST', body: JSON.stringify({ - ...data, + ...params, i: credential !== undefined ? credential : this.credential }), credentials: 'omit', diff --git a/src/endpoints.ts b/src/endpoints.ts index 9998fb6225..99804e1829 100644 --- a/src/endpoints.ts +++ b/src/endpoints.ts @@ -1,5 +1,6 @@ import { - Ad, Announcement, Antenna, App, AuthSession, Clip, DriveFile, DriveFolder, GalleryPost, InstanceMetadata, + Ad, Announcement, Antenna, App, AuthSession, Clip, DetailedInstanceMetadata, DriveFile, DriveFolder, GalleryPost, InstanceMetadata, + LiteInstanceMetadata, Note, OriginType, Page, ServerInfo, Stats, User, UserGroup, UserList, UserSorting } from './entities'; @@ -257,7 +258,15 @@ export type Endpoints = { 'messaging/messages/read': { req: TODO; res: TODO; }; // meta - 'meta': { req: { detail?: boolean; }; res: InstanceMetadata; }; // TODO: 「detail が true なら DetailedInstanceMetadata を返す」のような型付けをしたい + 'meta': { req: { detail?: boolean; }; res: { + $switch: { + $cases: [[ + { detail: true; }, + DetailedInstanceMetadata, + ]]; + $default: LiteInstanceMetadata; + }; + }; }; // miauth 'miauth/gen-token': { req: TODO; res: TODO; };