Adjust React's setState to work in more edge cases (#22236)

* Adjust React's setState to work in more edge cases

Fixes DefinitelyTyped/DefinitelyTyped#22230
Fixes DefinitelyTyped/DefinitelyTyped#18365

* Restore test and naming I lost
This commit is contained in:
Eric Anderson
2017-12-15 16:50:19 -05:00
committed by John Reilly
parent 73044764a8
commit 6bf1827a0a
4 changed files with 36 additions and 4 deletions

View File

@@ -282,8 +282,9 @@ declare namespace React {
// We MUST keep setState() as a unified signature because it allows proper checking of the method return type.
// See: https://github.com/DefinitelyTyped/DefinitelyTyped/issues/18365#issuecomment-351013257
// Also, the ` | S` allows intellisense to not be dumbisense
setState<K extends keyof S>(
state: ((prevState: Readonly<S>, props: P) => (Pick<S, K> & Partial<S>)) | (Pick<S, K> & Partial<S>),
state: ((prevState: Readonly<S>, props: P) => (Pick<S, K> | S)) | (Pick<S, K> | S),
callback?: () => any
): void;

View File

@@ -78,7 +78,8 @@ const StatelessComponentWithoutProps: React.SFC = (props) => {
</React.Fragment>
</div>;
class Comp extends React.Component<{}, { foo: boolean, bar: boolean }> {
// Below tests that setState() works properly for both regular and callback modes
class SetStateTest extends React.Component<{}, { foo: boolean, bar: boolean }> {
handleSomething = () => {
this.setState({ foo: '' }); // $ExpectError
this.setState({ foo: true });
@@ -94,3 +95,17 @@ class Comp extends React.Component<{}, { foo: boolean, bar: boolean }> {
this.setState({ foo: true, bar: undefined}); // $ExpectError
}
}
// Below tests that extended types for state work
export abstract class SetStateTestForExtendsState<P, S extends { baseProp: string }> extends React.Component<P, S> {
foo() {
this.setState({ baseProp: 'foobar' });
}
}
// Below tests that & generic still works
export abstract class SetStateTestForAndedState<P, S> extends React.Component<P, S & { baseProp: string }> {
foo() {
this.setState({ baseProp: 'foobar' });
}
}

View File

@@ -284,8 +284,9 @@ declare namespace React {
// We MUST keep setState() as a unified signature because it allows proper checking of the method return type.
// See: https://github.com/DefinitelyTyped/DefinitelyTyped/issues/18365#issuecomment-351013257
// Also, the ` | S` allows intellisense to not be dumbisense
setState<K extends keyof S>(
state: ((prevState: Readonly<S>, props: P) => (Pick<S, K> & Partial<S>)) | (Pick<S, K> & Partial<S>),
state: ((prevState: Readonly<S>, props: P) => (Pick<S, K> | S)) | (Pick<S, K> | S),
callback?: () => any
): void;

View File

@@ -64,7 +64,8 @@ const StatelessComponentWithoutProps: React.SFC = (props) => {
};
<StatelessComponentWithoutProps />;
class Comp extends React.Component<{}, { foo: boolean, bar: boolean }> {
// Below tests that setState() works properly for both regular and callback modes
class SetStateTest extends React.Component<{}, { foo: boolean, bar: boolean }> {
handleSomething = () => {
this.setState({ foo: '' }); // $ExpectError
this.setState({ foo: true });
@@ -80,3 +81,17 @@ class Comp extends React.Component<{}, { foo: boolean, bar: boolean }> {
this.setState({ foo: true, bar: undefined}); // $ExpectError
}
}
// Below tests that extended types for state work
export abstract class SetStateTestForExtendsState<P, S extends { baseProp: string }> extends React.Component<P, S> {
foo() {
this.setState({ baseProp: 'foobar' });
}
}
// Below tests that & generic still works
export abstract class SetStateTestForAndedState<P, S> extends React.Component<P, S & { baseProp: string }> {
foo() {
this.setState({ baseProp: 'foobar' });
}
}