模拟use-History挂钩的react-router-dom会导致以下错误-TS2698:传播类型只能从对象类型创建

发布时间:2020-07-07 12:07

我试图在一个测试用例中模拟react-router-dom,以使useHistory钩子在我的测试中起作用。我决定使用jest.mock模拟整个模块,并使用jest.requireActual保留我可能不想模拟的其他属性。

jest.mock('react-router-dom', () => ({
  ...jest.requireActual('react-router-dom'),
  useHistory: () => ({
    location: {
      pathname: '/list',
    },
  }),
}));

这实际上来自对以下问题的高度评价的解决方案之一:How to mock useHistory hook in jest?

但是,TypeScript编译器在下一行...jest.requireActual('react-router-dom'),

上标记了以下错误

TS2698:传播类型只能从对象类型创建。

有趣的是,我仅在将jest和ts-jest更新到最新版本(jest v26)之后才遇到此问题。使用jest 24.x.x时,我没有遇到任何这些问题。

"@types/jest": "^26.0.4",
"jest": "^26.1.0",
"ts-jest": "^26.1.1",

有人知道如何解决最新的玩笑版本吗?

回答1

jest.requireActual返回无法传播的unknown类型。

正确的类型是:

import * as ReactRouterDom from 'react-router-dom';

jest.mock('react-router-dom', () => ({
  ...jest.requireActual('react-router-dom') as typeof ReactRouterDom,
  useHistory: ...,
}));

一个快速解决方法是any

jest.mock('react-router-dom', () => ({
  ...jest.requireActual('react-router-dom') as any,
  useHistory: ...,
}));

可以接受,因为在这种情况下它不会损害类型安全性。

由于react-router-dom是ES模块,因此模拟它的一种更正确的方法是:

jest.mock('react-router-dom', () => ({
  ...jest.requireActual('react-router-dom') as any,
  __esModule: true,
  useHistory: ...,
}));