javascript - Grundläggande HOC med Enzyme och TypeScript


Jag har en HOC att testa, under shallow mount borde jag kalla några klassmetoder:

it('Should not call dispatch', () => {
        const dispatch = jest.fn()
        const WrappedComponent = someHoc(DummyComponent)
        const instance = shallow(
          <WrappedComponent
            dispatch={dispatch}
          />,
        ).instance() as WrappedComponent
        instance.someMethod()
        expect(dispatch).toHaveBeenCalledTimes(0)
})

test fungerar bra men TS-kompilatorn ger ett fel

 Cannot find name 'WrappedComponent'.

Och det är korrekt eftersom WrappedComponent inte är en typ eller klass, men om jag tar bort

 as WrappedComponent

rad, TS kastar ett fel

Property 'someMethod' does not exist on type 'Component<{}, {}, any>'.

Dessutom kompilerar det inte om jag ändrar den raden till

as typeof WrappedComponent

someHoc beskrivning:

import ...

interface State {
  /*state*/
}

interface Props {
  dispatch: Dispatch<Action>
  /*props*/
}

export someHoc = <T extends {}>(
  ChildComponent: React.ComponentClass<T>,
) => {
  class Wrapper extends React.PureComponent<T & Props, State> {

    someMethod = () => {
       /*do smth*/
    }

    render() {
      return (
        <div>
          <ChildComponent {...this.props} />
        </div>
      )
    }
  }

  return Wrapper
}

Hur kan jag skriva HOC-instansen? Tack.

Svar #1

Det förväntas att funktioner som har varierande returvärdestyper som kan parametriseras är generiska. shallow är en generisk:

export function shallow<C extends Component, P = C['props'], S = C['state']>(node: ReactElement<P>, options?: ShallowRendererProps): ShallowWrapper<P, S, C>;
export function shallow<P>(node: ReactElement<P>, options?: ShallowRendererProps): ShallowWrapper<P, any>;
export function shallow<P, S>(node: ReactElement<P>, options?: ShallowRendererProps): ShallowWrapper<P, S>;

Det bör troligen användas som:

const instance = shallow<typeof WrappedComponent>(
  <WrappedComponent
    dispatch={dispatch}
  />,
).instance();

Det verkar för närvarande finnas problem i Enzyme-typningar med att använda generiska parametrar för att härleda komponenttyp i ShallowWrapper.

Ett sätt att kringgå som säkrar typ-säkerhet ända ner i testet är att fastställa typen:

const instance = shallow(
  <WrappedComponent
    dispatch={dispatch}
  />,
)
.instance() as any as InstanceType<typeof WrappedComponent>;

Svar #2

Detta handlar inte om HOC, men om någon hittar detta efter att ha googlat i timmar, försök att uppdatera @types/react till den senaste versionen (jag gick från 18.0.14 till 18.2.38).

Vilket tillät mig att använda (omodifierad)

const about = shallow(<About />);

given

export default function About() {
  const foo = true;
  return (
    <div>Blabla</div>
  )
}

utan problem.

Relaterade artiklar