Skip to content

Commit

Permalink
Merge pull request #168 from bitgopatmcl/output-type-errors
Browse files Browse the repository at this point in the history
feat: produce helpful error messages on httpRequest codec errors
  • Loading branch information
ericcrosson-bitgo authored Jul 19, 2022
2 parents 8195fa0 + 14343c6 commit 4673303
Show file tree
Hide file tree
Showing 2 changed files with 37 additions and 9 deletions.
42 changes: 37 additions & 5 deletions packages/io-ts-http/src/httpRequest.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import * as t from 'io-ts';
import { Json } from 'io-ts-types';
import { flattened, optional, optionalized } from './combinators';
import { OutputConstrainedProps } from './utils';

export const GenericHttpRequest = optionalized({
// DISCUSS: renaming this to something more specific, e.g. route, or path, or routeParams, or pathParams
Expand All @@ -18,13 +17,46 @@ export type HttpRequestCodec<T> = t.Type<
>;

export type HttpRequestCombinatorProps = {
params?: NonNullable<OutputConstrainedProps<string | undefined>>;
query?: NonNullable<OutputConstrainedProps<string | string[] | undefined>>;
headers?: NonNullable<OutputConstrainedProps<string | undefined>>;
params?: NonNullable<t.Props>;
query?: NonNullable<t.Props>;
headers?: NonNullable<t.Props>;
body?: NonNullable<t.Props>;
};

export function httpRequest<Props extends HttpRequestCombinatorProps>(props: Props) {
/**
* Attempts to produce a helpful error message when invalid codecs are passed to `httpRequest`
* It is a workaround until something like https://github.com/microsoft/TypeScript/pull/40468
* is merged.
*/
type EmitOutputTypeErrors<
P extends t.Props | undefined,
O,
OName extends string,
> = P extends undefined
? P
: {
[K in keyof P & string]: P[K] extends t.Type<any, O, any>
? P[K]
: `Codec's output type is not assignable to ${OName}. Try using one like \`NumberFromString\``;
};

type EmitPropsErrors<P extends HttpRequestCombinatorProps> = {
params?: EmitOutputTypeErrors<P['params'], string | undefined, 'string | undefined'>;
query?: EmitOutputTypeErrors<
P['query'],
string | string[] | undefined,
'string | string[] | undefined'
>;
headers?: EmitOutputTypeErrors<
P['headers'],
string | undefined,
'string | undefined'
>;
};

export function httpRequest<
Props extends HttpRequestCombinatorProps & EmitPropsErrors<Props>,
>(props: Props) {
return flattened('httpRequest', {
query: {},
params: {},
Expand Down
4 changes: 0 additions & 4 deletions packages/io-ts-http/src/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,10 +26,6 @@ export type OptionalizedC<Props extends t.Props> = t.IntersectionC<
[t.TypeC<RequiredProps<Props>>, t.PartialC<OptionalProps<Props>>]
>;

export type OutputConstrainedProps<O> = {
[K: string]: t.Type<any, O, unknown>;
};

export type NestedProps = {
[K: string]: t.Props;
};
Expand Down

0 comments on commit 4673303

Please sign in to comment.