user1032752
user1032752

Reputation: 871

Typescript not assignable error after explicit type check

Given the following function that returns a JSX component:

const getListContent = () => {
    switch (true) {
        case loading:
            return <ListLoadingIndicator/>;
        case error !== undefined:
            return <ListError error={error}/>;
        default:
            return <ListContent/>
    }
};

The Typescript compiler complains that error is not assignable to the ListError component because the ListError interface expects error to be of type Error but this component's interface allows for a type of Error | undefined.

Adding a bang <ListError error={error!}/> fixes the issue but I want to understand why the compiler thinks that error may be undefined after I explicitly check that it's not.

Upvotes: 0

Views: 159

Answers (2)

jcalz
jcalz

Reputation: 327754

Basically, control flow analysis for switch statements in TypeScript will narrow the type of the switched value, not the type of other values. So, switch (true) {} will only possibly narrow true to something else, which is not useful to you. And it doesn't look like the TypeScript folks have any interest in changing this, at least as of 2016.

My suggestion is to do your if or switch or ? tests directly on values you'd like to narrow. If you want error to narrow from Error | undefined to just Error, you should be checking error directly. For example, the following should work:

const getListContent = () => {
  if (loading) return <ListLoadingIndicator />;
  if (error !== undefined) return <ListError error={error} />;
  return <ListContent />
};

which suggests the following terser syntax:

const getListContent = () =>
  loading ? <ListLoadingIndicator /> :
    error ? <ListError error={error} /> :
      <ListContent />;

which should also work. Okay, hope that helps; good luck!

Upvotes: 2

Pace
Pace

Reputation: 43807

There is some discussion of it here https://github.com/Microsoft/TypeScript/issues/2214 where electricessence basically states that switch statements that are not constants, while allowed, are non-normative cases and so not all features may work as expected. Basically this is not something that TypeScript currently handles. You could open a feature request for it. I couldn't find an open one in my brief search.

Upvotes: 1

Related Questions