Phil Lucks
Phil Lucks

Reputation: 3983

how to conditionally declare a type without function, based on boolean variable?

I tried reading the docs for Conditional type declarations, but I am missing something still. How can I declare a type that is based on a conditional prop my component receives where I don't need to make a function to access the boolean?

Something like:

type ConditionalResponse =  myFlag ? CommonApiGeneric<{ items: SomeShape[] }> : CommonApiGeneric<{ entries: SomeShape[] }>;

Here is a TS Sandbox that shows code example of what I am trying to do.

I believe I can fallback to a union type declaration, but this conditional would be very handy...

EDIT: In the meantime, i have done this where my key is [x: string]:

const { data, isValidating } = useVaporSwr<
    OldPaginatedResponseGeneric<{
      [x: string]: ItemsShape[];
    }>
  >({
    key: url,
    fetcher: () => getRequest(isElixir ? API.ELIXIR : API.PLASMA2, url),
  });
  const key = isElixir ? 'items' : 'entries';
  const rows = data?.[key] || [];

Upvotes: 1

Views: 436

Answers (1)

CertainPerformance
CertainPerformance

Reputation: 371233

You can make the function generic and have the myFlag extend true | false. (Don't use boolean, because then you won't have the information you need to type the response correctly.) With that flag type, you can then specify the CommonApiGeneric you need and pass it.

I'd use Object.values to get the (only) value from the returned object, that way you don't have to mess with the differing response object shape.

const MyComponent = <T extends true | false>({ myFlag }: { myFlag: T }) => {
    type ConditionalResponse = T extends true
        ? CommonApiGeneric<{ items: SomeShape[] }>
        : CommonApiGeneric<{ entries: SomeShape[] }>;
    const { data, isValidating } = useSwr<ConditionalResponse>({
        key: url,
        fetcher: () => getRequest(myFlag ? API.ELIXIR : API.PLASMA2, url),
    });
    const rows = Object.values(data.data)[0];

Upvotes: 1

Related Questions