Preact: setState typescript signature is too restrictive.

Created on 21 Dec 2016  Â·  7Comments  Â·  Source: preactjs/preact

The typescript signature of setState is too restrictive, since it assumes it's parameter must be exactly the type of the component's StateType type parameter.

TypeScript has a builtin type Partial<T> that has the same type as T, but with all properties forced to be optional defined as:

type Partial<T> = {
    [P in keyof T]?: T[P];
}

And define the signature of setState to be setState(state: Partial<StateType>, opts?: any).

I'll PR this in when I have a moment!

documentation help wanted

Most helpful comment

Also have the same problem.

If I describe my State as strong set of options:

interface MyState
{
    option1: string;
    option2: string[];
}

I can't set only one option in set:

this.setState(
    {option1: 'Hello'}, // Error: Property 'option2' is missing
);

But if I mark options with ?:

interface MyState
{
    option1?: string;
    option2?: string[];
}

I have another problem – TypeScript think that options can be undefined (but I set them in constructor):

const option2 = [...this.state.option2, 'new']; // Error

So wating for

setState(state: Partial<StateType>, opts?: any): void;

All 7 comments

The PR is https://github.com/developit/preact/pull/467

This sounds good, although I'll note that Partial<T> (and more specifically, keyof) is a recent addition that was only introduced in TypeScript 2.1, so accepting this change would break compatibility for anyone using an older version of TypeScript.

@robertknight agreed, and the @types/react library doesn't have this addition yet either, fwiw.

Also have the same problem.

If I describe my State as strong set of options:

interface MyState
{
    option1: string;
    option2: string[];
}

I can't set only one option in set:

this.setState(
    {option1: 'Hello'}, // Error: Property 'option2' is missing
);

But if I mark options with ?:

interface MyState
{
    option1?: string;
    option2?: string[];
}

I have another problem – TypeScript think that options can be undefined (but I set them in constructor):

const option2 = [...this.state.option2, 'new']; // Error

So wating for

setState(state: Partial<StateType>, opts?: any): void;

So it should be Pick instead of Partial.

I think Preact definitions can be updated to solutions from React, when processes in related issues will be done.

After TS 2.1.5 comes out, we should be able to merge the react changes.

In favor for the merging #467.

For pre-2.1.x, I've been asserting my setState() where necessary.

interface State {
  foo: string;
  bar: string;
}

this.setState({ foo: 'hello' } as State); // no errors

This should also work if you're using React.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

kossnocorp picture kossnocorp  Â·  3Comments

philipwalton picture philipwalton  Â·  3Comments

mizchi picture mizchi  Â·  3Comments

youngwind picture youngwind  Â·  3Comments

paulkatich picture paulkatich  Â·  3Comments