Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Optional Types Don't Play Well with httpRoute and httpRequest #139

Open
timmyhartke2 opened this issue Jun 30, 2022 · 2 comments
Open

Optional Types Don't Play Well with httpRoute and httpRequest #139

timmyhartke2 opened this issue Jun 30, 2022 · 2 comments

Comments

@timmyhartke2
Copy link

timmyhartke2 commented Jun 30, 2022

Attempting to use optionalized, or a combination of type, partial, and intersection as shown here results in an error from httpRequest. For example, if we define exampleRequestBody as

export const exampleRequestBody = optionalized({
  exampleId: t.number,
  date: t.string,
  optionalParameter: optional(t.number),
});

export type ExampleRequestBody = t.TypeOf<typeof ExampleRequestBody>;

And we define our example httpRoute as ExampleHttpRoute:

export const ExampleHttpRoute = httpRoute({
  path: 'example/api/path',
  method: 'POST',
  request: httpRequest({
    body: exampleRequestBody,
    headers: {
      'apikey': NonEmptyString,
    },
  }),
  response: {
    200: ExampleResponseBody,
  },
});

Then we get this error back:

TS2322: Type 'Type<never, { params: {} & {}; query: {} & {}; headers: { 'apikey': string; } & {}; body: {} & { readonly _A?: unknown; 
readonly _O?: unknown; readonly types?: unknown; readonly _tag?: unknown; readonly name?: unknown; readonly is?: unknown; readonly validate?: unknown; ... 5 more ...; decode?: unknown; }; }, unk...' is not assignable to type 'HttpRequestCodec<any>'. 
Types of property 'encode' are incompatible. Type 'Encode<never, { params: {} & {}; query: {} & {}; headers: { 'apikey': string; } & {};
body: {} & { readonly _A?: unknown; readonly _O?: unknown; readonly types?: unknown; readonly _tag?: unknown; readonly name?:
unknown; readonly is?: unknown; readonly validate?: unknown; ... 5 more ...; decode?: unknown; }; }>' is not assignable to type 
'Encode<any, { params: { [x: string]: string; }; query: { [x: string]: string | string[]; }; } & { headers?: { [x: string]: string; } | undefined;
body?: Json | undefined; }>'.       Type 'any' is not assignable to type 'never'.

There is a workaround for certain situations, but not all. If your schema does not have optional attributes at the top level, for example, then you can do this:

export const exampleRequestBody = {
  exampleId: t.number,
  date: t.string,
  optional_data: optionalized({
    optionalParameter: optional(t.number)
  })
};

However, if you need to define an optional attribute at the top level of your schema (such as in the first example), this does not work. This is a problem when, for example, you are writing a schema for external API's request/response body. If that API has optional attributes at the top level of the request/response body, there is not currently a clean way to deal with that using this library.

@timmyhartke2
Copy link
Author

I opened the problem in the wrong place. Closing.

@timmyhartke2 timmyhartke2 closed this as not planned Won't fix, can't repro, duplicate, stale Jun 30, 2022
@ericcrosson-bitgo
Copy link
Contributor

@timmyhartke2 this is a reasonable place for this discussion

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants