Closed
Description
TypeScript Version:
3.8.0-dev.20191119
3.7.2
Search Terms:
Redux
Connect
Union
Code
const mapStateToProps = (state?: {}) => !state ? {} : { foo: 1 };
type Props = ReturnType<typeof mapStateToProps>;
const MyComponent = (props: Props) => null;
// Simplified from react
type FunctionComponent<P> = (props: P & { children: {} }) => null;
// Simplified from react-redux
type Matching<InjectedProps, DecorationTargetProps> = {
[P in keyof DecorationTargetProps]: P extends keyof InjectedProps
? InjectedProps[P] extends DecorationTargetProps[P]
? DecorationTargetProps[P]
: InjectedProps[P]
: DecorationTargetProps[P];
};
// Simplified from react-redux
type InferableComponentEnhancerWithProps =
<C extends FunctionComponent<Matching<Props, Props>>>(
component: C
) => never;
(window as any as InferableComponentEnhancerWithProps)(MyComponent);
Expected behavior:
Code should compile without error. This works on 3.6.3 and below.
Actual behavior:
demo.ts:25:56 - error TS2345: Argument of type '(props: { foo?: undefined; } | { foo: number; }) => null' is not assignable to parameter of type 'FunctionComponent<Matching<{ foo?: undefined; } | { foo: number; }, { foo?: undefined; }> | Matching<{ foo?: undefined; } | { foo: number; }, { foo: number; }>>'.
Types of parameters 'props' and 'props' are incompatible.
Type '(Matching<{ foo?: undefined; } | { foo: number; }, { foo?: undefined; }> & { children: {}; }) | (Matching<{ foo?: undefined; } | { foo: number; }, { foo: number; }> & { children: {}; })' is not assignable to type '{ foo?: undefined; } | { foo: number; }'.
Type 'Matching<{ foo?: undefined; } | { foo: number; }, { foo?: undefined; }> & { children: {}; }' is not assignable to type '{ foo?: undefined; } | { foo: number; }'.
Type 'Matching<{ foo?: undefined; } | { foo: number; }, { foo?: undefined; }> & { children: {}; }' is not assignable to type '{ foo: number; }'.
Types of property 'foo' are incompatible.
Type 'number | undefined' is not assignable to type 'number'.
Type 'undefined' is not assignable to type 'number'.
We encountered this in a very large React/Redux project after attempting to update to 3.7.2.
I simplified the repro case as best I could.
Apologies for the title, I don't know the best terminology for this situation.
Playground Link:
Link
Note that the playground doesn't show a behavior change from 3.7.2 to 3.6.3, but VS Code and the command-line tsc
do.
Related Issues:
#33872 - Seems similar and broke at the same time