From 7143029c6263f1b7ad870751d874e6f247ba3087 Mon Sep 17 00:00:00 2001 From: Patrick McLaughlin Date: Thu, 4 Aug 2022 10:05:56 -0400 Subject: [PATCH] fix: attempt to handle response types more cleanly Redefines a "service function" so that the return type is either all numeric or all keyed. This is a bit of a guess, but the hope is that it resolves some of the weird typechecking issues we are seeing around response types. --- packages/express-wrapper/src/index.ts | 6 +++--- packages/express-wrapper/src/request.ts | 15 +++++++++------ packages/express-wrapper/src/response.ts | 16 +++++++--------- packages/io-ts-http/src/httpResponse.ts | 2 +- 4 files changed, 20 insertions(+), 19 deletions(-) diff --git a/packages/express-wrapper/src/index.ts b/packages/express-wrapper/src/index.ts index ce236d20..8c996d5f 100644 --- a/packages/express-wrapper/src/index.ts +++ b/packages/express-wrapper/src/index.ts @@ -11,9 +11,9 @@ import { apiTsPathToExpress } from './path'; import { decodeRequestAndEncodeResponse, RouteHandler } from './request'; import { defaultResponseEncoder, ResponseEncoder } from './response'; -export { middlewareFn } from './middleware'; -export type { ResponseEncoder, NumericOrKeyedResponseType } from './response'; -export { routeHandler } from './request'; +export { middlewareFn, MiddlewareChain, MiddlewareChainOutput } from './middleware'; +export type { ResponseEncoder, KeyedResponseType } from './response'; +export { routeHandler, ServiceFunction } from './request'; const isHttpVerb = (verb: string): verb is 'get' | 'put' | 'post' | 'delete' => verb === 'get' || verb === 'put' || verb === 'post' || verb === 'delete'; diff --git a/packages/express-wrapper/src/request.ts b/packages/express-wrapper/src/request.ts index ba2c797d..14689ef4 100644 --- a/packages/express-wrapper/src/request.ts +++ b/packages/express-wrapper/src/request.ts @@ -7,7 +7,7 @@ import express from 'express'; import * as E from 'fp-ts/Either'; import * as PathReporter from 'io-ts/lib/PathReporter'; -import { HttpRoute, RequestType } from '@api-ts/io-ts-http'; +import { HttpRoute, RequestType, ResponseType } from '@api-ts/io-ts-http'; import { runMiddlewareChain, @@ -16,11 +16,11 @@ import { MiddlewareChain, MiddlewareChainOutput, } from './middleware'; -import type { NumericOrKeyedResponseType, ResponseEncoder } from './response'; +import type { KeyedResponseType, ResponseEncoder } from './response'; -export type ServiceFunction> = ( - input: Input, -) => NumericOrKeyedResponseType | Promise>; +export type ServiceFunction> = + | ((input: Input) => ResponseType | Promise>) + | ((input: Input) => KeyedResponseType | Promise>); // The first two alternatives are here to maintain backwards compatibility export type RouteHandler = @@ -109,7 +109,10 @@ export const decodeRequestAndEncodeResponse = ( return; } - let rawResponse: NumericOrKeyedResponseType | undefined; + let rawResponse: + | ResponseType + | KeyedResponseType + | undefined; try { const handlerParams = MiddlewareBrand in handler diff --git a/packages/express-wrapper/src/response.ts b/packages/express-wrapper/src/response.ts index 03efe2c1..75fc648b 100644 --- a/packages/express-wrapper/src/response.ts +++ b/packages/express-wrapper/src/response.ts @@ -8,20 +8,18 @@ import { ResponseType, } from '@api-ts/io-ts-http'; -export type NumericOrKeyedResponseType = - | ResponseType - | { - [Key in keyof R['response'] & keyof HttpToKeyStatus]: { - type: HttpToKeyStatus[Key]; - payload: t.TypeOf; - }; - }[keyof R['response'] & keyof HttpToKeyStatus]; +export type KeyedResponseType = { + [Key in keyof R['response'] & keyof HttpToKeyStatus]: { + type: HttpToKeyStatus[Key]; + payload: t.TypeOf; + }; +}[keyof R['response'] & keyof HttpToKeyStatus]; // TODO: Use HKT (using fp-ts or a similar workaround method, or who knows maybe they'll add // official support) to allow for polymorphic ResponseType<_>. export type ResponseEncoder = ( route: HttpRoute, - serviceFnResponse: NumericOrKeyedResponseType, + serviceFnResponse: ResponseType, ) => express.RequestHandler; export const defaultResponseEncoder: ResponseEncoder = diff --git a/packages/io-ts-http/src/httpResponse.ts b/packages/io-ts-http/src/httpResponse.ts index cbbb8996..c76db03e 100644 --- a/packages/io-ts-http/src/httpResponse.ts +++ b/packages/io-ts-http/src/httpResponse.ts @@ -1,7 +1,7 @@ import * as t from 'io-ts'; export type HttpResponse = { - [K: number]: t.Mixed; + [K: number | string]: t.Mixed; }; export type ResponseTypeForStatus<