Reputation: 871
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
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
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