1

I have the following interface:

export interface withAuthState {
  ready: boolean,
  session: any
}

And the following HOC:

const withAuth = <P extends withAuthProps, S extends withAuthState>(
  WrappedComponent: new (props: P) => RX.Component<P, S>
) =>    class WithAuth extends RX.Component<P & withAuthProps, S & withAuthState> {
        constructor(props) {
          super(props);

          this.state = {
            ready: false,
            session: null
          };
        }
    }

I'm unable to set the state in the constructor. The error is:

TS2322: Type '{ ready: false; session: null; }' is not assignable to type 'Readonly<S & withAuthState>'.

I'm clearly missing something here, but I do not know what.

Any help appreciated. Thanks in advance.

1 Answers1

0

The problem is that the state may have other properties, which you can't initialize because you don't know about them in your HOC. Consider the following:

class MyComponent extends RX.Component<withAuthProps, withAuthState & { myStateProp: number }>{}    
const MyComponentWithAuth = withAuth(MyComponent);
let comp = new MyComponentWithAuth({});
// myStateProp does not exist on state because you did not initialize it in your HOC even though the property is required
comp.state.myStateProp 

If you are ok with this behavior, you can just use a type assertion when you initialize the state:

this.state = {
    ready: false,
    session: null
} as S & withAuthState;
Titian Cernicova-Dragomir
  • 230,986
  • 31
  • 415
  • 357
  • The type assertion does not compile. I have 3 errors. Identifier expected. The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. 'S' only refers to a type, but is being used as a value here. –  Mar 14 '18 at 09:16
  • @OlivierMATROT wops, you are in a tsx, `<>` does not work for assertions, you must use `as`, will update in a second – Titian Cernicova-Dragomir Mar 14 '18 at 09:19