aspida / aspida

TypeScript friendly HTTP client wrapper for the browser and node.js.

Home Page:https://github.com/aspida/aspida

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

tagged/discriminated union support not working?

tgpfeiffer opened this issue · comments

Description

I am using Aspida in my React app like

const { data, error } = useAspidaSWR(client?.status, {
    enabled: !!client,
    refreshInterval: 1000,
});

and want to process a server response that is a discriminated union (defined with oneOf using OpenAPI, cf. https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.2.md#discriminatorObject). However, server responses matching one of the variants cannot be parsed and both data and error in the code example above are undefined.

Details

When my types (created in the @types/index.ts file created by openapi2aspida) look like

export type Unavailable = {
  name: string
}

export type Idle = {
  name: string
  foo: number
}

then the HTTP call is made and for a JSON server response {"name": "Unavailable"} I get a valid object as data, but if I define the types like

export type Unavailable = {
  name: 'Unavailable'
}

export type Idle = {
  name: 'Idle'
  foo: number
}

as described in https://www.fullstory.com/blog/discriminated-unions-and-exhaustiveness-checking-in-typescript/ then both data and error are undefined and I think not even the HTTP request is made (not 100% sure, not in my work environment right now).

I would like to process the API response like

  switch (data.name) {
    case 'Unavailable':
      return <p>Unavailable</p>;
    case 'Idle':
      return <p>Idle: {data.foo}</p>;
    default:
      assertExhaustive(data);
      return <div />;
  }

but that only works if the strings are hardcoded literals in the type definitions.

Is this supposed to work at all? If not, how else would I work with tagged unions using Aspida?

Environment

  • Package version: v1.7.1
  • OS:
    • Linux
    • Windows
    • macOS
  • Node.js version: v16.6.2
  • npm version: 7.20.3

Additional context

I can come up with a minimal example if needed, but maybe someone already has an explanation why that doesn't work or what I am doing wrong. Thanks!

Never mind, this was an issue on my side with the client not being initialized correctly. Using a tagged union with string literals as the name value works fine and as expected 👍