A RetroSearch Logo

Home - News ( United States | United Kingdom | Italy | Germany ) - Football scores

Search Query:

Showing content from https://github.com/DefinitelyTyped/DefinitelyTyped/issues/18365 below:

On the use of Pick for @types/react's setState · Issue #18365 · DefinitelyTyped/DefinitelyTyped · GitHub

I understand that Pick was used for the type of setState because returning undefined for a key that should not be undefined would result in the key being set to undefined by React.

However, using Pick causes other problems. For one, the compiler service's autocomplete becomes useless, as it uses the result of the Pick for autocompletion, and when you request completions the Pick's result doesn't yet contain the key you may want to autocomplete. But the problems are particularly bad when writing setState with a callback argument:

  1. The list of keys is derived from your first return statement; if you don't return a particular key in your return statement you also can't read it in the argument without forcing the list of keys to reset to never. Multiple return statements can be hard to write if they return different keys, especially if you have an undefined return somewhere (e.g. if (state.busy) { return }).
  2. If, for some reason, the type you are returning is not compatible with the input type, the Pick will choose never for its keys, and the function will be allowed to return anything. Even keys that coincide with an existing key effectively allow any as a value -- if it doesn't fit, it's just not Picked, and is treated as an excess property for {}, which is not checked.
  3. If never is picked as the generic argument, for any of the reasons listed above, a callback argument may actually be treated as an argument to the object form of setState; this causes the callback's arguments to be typed any instead of {}. I am not sure why this is not an implicit any error.
interface State {
  count: string // (for demonstration purposes)
}

class Counter extends React.Component<{}, State> {
  readonly state: Readonly<State> = {
    count: '0'
  }

  render () {
    return React.createElement('span', { onClick: this.clicked }, this.state.count)
  }

  private readonly clicked = () => {
    this.setState(input => ({
      count: +input.count + 1 // not a type error
      // the setState<never>(input: Pick<State, never>) overload is being used
    }))
  }
}

To sum it up, while the use of Pick, despite some inconvenience, help catch type errors in the non-callback form of setState, it is completely counter-productive in the callback form; where it not only does not do the intended task of forbidding undefined but also disables any type checking at all on the callback's inputs or outputs.

Perhaps it should be changed, at least for the callback form, to Partial and hope users know to not return undefined values, as was done in the older definitions.

mathiasaa, xStrom and mahitechnologies259


RetroSearch is an open source project built by @garambo | Open a GitHub Issue

Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo

HTML: 3.2 | Encoding: UTF-8 | Version: 0.7.4