Closed
Description
TypeScript Version: 2.1.4 / nightly (2.2.0-dev.20170108 )
Code
Pick
is supposed to work for typing React.setState (#12793).
However, there is a problem if you want to conditionally change which attributes to update.
declare class Component<P, S> {
setState<K extends keyof S>(f: (prevState: S, props: P) => Pick<S, K>, callback?: () => any): void;
}
declare const component: Component<{}, {
foo: number;
bar: string;
someCondition: boolean;
}>;
component.setState(({ someCondition }) => {
if (someCondition) {
return { foo: 0 };
} else {
return { bar: '' };
}
});
Expected behavior:
The code compiles successfully.
Actual behavior:
component.setState
line in the above code emits an error.
error TS2345: Argument of type '({someCondition}: { foo: number; bar: string; someCondition: boolean; }) => { foo: number; } | { ...' is not assignable to parameter of type '(prevState: { foo: number; bar: string; someCondition: boolean; }, props: {}) => Pick<{ foo: numb...'.
Type '{ foo: number; } | { bar: string; }' is not assignable to type 'Pick<{ foo: number; bar: string; someCondition: boolean; }, "foo" | "bar">'.
Type '{ foo: number; }' is not assignable to type 'Pick<{ foo: number; bar: string; someCondition: boolean; }, "foo" | "bar">'.
Property 'bar' is missing in type '{ foo: number; }'.
You have to write like this to avoid the error.
component.setState(({ foo, bar, someCondition }) => {
if (someCondition) {
return { foo: 0, bar };
} else {
return { foo, bar: '' };
}
});