Skip to content

Properly infer the type for a given match #3

Description

@ythecombinator

Description

Given this sample interface:

declare let fetchState:
  | { status: "loading" }
  | { status: "success"; data: string }
  | { status: "error" };

We could have switch-based braching:

export default function MyComponent() {
  return (
    <div>
      {(() => {
        switch (fetchState.status) {
          case "loading":
            return <p>Loading</p>;
          case "success":
            return <p>{fetchState.data}</p>;
          case "error":
            return <p>Oops</p>;
        }
      })()}
    </div>
  );
}

In order to be able to replace this snippet with our library, ie.:

export default function MyComponent() {
  return (
      <Match value={fetchState}>
        <With status="loading">
          <p>Loading</p>
        </With>
        <With status="success">
          <p>{fetchState.data}</p>
        </With>
        <With status="error">
          <p>Oops</p>
        </With>
        <Otherwise>Fallback</Otherwise>
      </Match>
  );
}

we'd need to ensure that when status is success, data exists. Instead, an error is thrown:

Property 'data' does not exist on type 'FetchState'.
  Property 'data' does not exist on type '{ status: "loading"; }'.ts(2339)

Probably, this should be addressed with some narrowing strategy (like type-predicates).

Resources

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions