TypeScript partial interface object

前端 未结 2 1310
自闭症患者
自闭症患者 2020-12-06 10:28

In React, the Component definition looks something like this:

class Component {
    state:S;
    setState(state:S):void;
}

And you

相关标签:
2条回答
  • 2020-12-06 11:02

    The react.d.ts definition is indeed wrong, and cannot be fixed until Partial Types are supported.

    The problem is that setState takes a partial state, which is a different type from normal state. You can solve this by manually specifying both types:

    interface MyState {
        name: string;
        age: number;
    }
    
    interface PartialMyState {
        name?: string;
        age?: number;
    }
    

    And manually declaring MyComponent without extending the provided React Component class:

    class MyComponent {
        state: MyState;
        setState(state:PartialMyState): void;
        //...
    }
    

    Which means you'll have to duplicate these function definitions for every subclass of Component in your code. You may be able to avoid this by defining a correct Component class generalized by an additional type of partial state:

    class CorrectComponent<S,P> { // generalized over both state and partial state
        state:S;
        setState(state:P):void;
        //...
    }
    
    class MyComponent extends CorrectComponent<MyState,PartialMyState> { }
    

    You'll still have to write a partial version for every state type you have.


    Alternatively, you can make setState non-typesafe by changing its argument's type to Object.

    0 讨论(0)
  • 2020-12-06 11:06

    "Partial types" are still missing in TypeScript currently, see TypeScript issue #4889 as well as this related question. I'm afraid it's not yet possible to make this type-check correctly.

    You might get away with marking all fields of your MyState interface as optional (by adding ? modifiers), but that in turn weakens the type-checking for things like Component.state (where you want all fields to be set).

    EDIT (December 2016): TypeScript 2.1 introduces mapped types, which supports describing partial types using Partial<T>! Now you can use the following type definition for Component:

    class Component<S> {
        state: S;
        setState(state: Partial<S>) : void;
    }
    
    0 讨论(0)
提交回复
热议问题