针对 useHistory 钩子模拟 React-router-dom 会导致以下错误 - TS2698:扩展类型只能从对象类型创建

问题描述 投票:0回答:3

我试图在我的一个测试用例中模拟

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",

有谁知道最新的 jest 版本如何解决这个问题吗?

reactjs typescript react-router jestjs react-hooks
3个回答
47
投票

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模块,更正确的mock方法是:

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

0
投票

万一有人在使用它而不是

typescript
时遇到这个问题,对我有用的是:
react-router-dom



0
投票
import ts from 'typescript'; jest.mock('typescript', () => ({ ...jest.requireActual('typescript') as Record<string, unknown>, nodeModuleNameResolver: ..., }));

即可满足 Typescript。它并不理想,因为类型不是很具体,但它完成了它的工作,并且绝对比

as object
:))
更好
as any

© www.soinside.com 2019 - 2024. All rights reserved.