TypeScript & React:组合高阶组件



我是使用React的TypeScript的新手,我在React中(已经(有两个HOC,我想compose它们,因为可能会有更多。

import { getIsAuthenticated } from 'features/user-authentication/user-authentication-reducer';
import { connect, ConnectedProps } from 'react-redux';
import { RootState } from 'redux/root-reducer';
import { withTranslation } from '../../../i18n';
import HomePageComponent from './home-page-component';
const mapStateToProps = (state: RootState) => ({
isAuthenticated: getIsAuthenticated(state),
});
const connector = connect(mapStateToProps);
export type PropsFromRedux = ConnectedProps<typeof connector>;
export default withTranslation()(connector(HomePageComponent));

这就是它目前的外观(以及工作/编译(。组件是:

// ...
import { TFunction } from 'next-i18next';
// ...
import { PropsFromRedux } from './home-page-container';
type Props = {
readonly t: TFunction;
} & PropsFromRedux;
const HomePageComponent = ({ isAuthenticated, t }: Props) => (
// ...

在JavaScript中,我通常会做:

export default compose(withTranslation(), connector)(HomePageComponent);

其中CCD_ 2来自Ramda或来自Redux本身。

使用Ramda的compose会抛出两个错误。

  1. connector:No overload matches this call.
  2. HomePageComponent:Expected 0 arguments, but got 1.

使用Redux的compose在这里编译,但破坏了我的测试。

import { render, screen } from 'tests/test-helpers';
import HomePageContainer from './home-page-container';
describe('Home Page Container', () => {
it('should render a greeting', () => {
render(<HomePageContainer />);
expect(screen.getByText(/hello world/i)).toBeInTheDocument();
});
});

在测试文件中,HomePageContainer抛出:

JSX element type 'HomePageContainer' does not have any construct or call signatures.

如何将compose用于高阶组件并使其与TypeScript一起工作?

附言:我在SO中找到了另一个问题和答案,但这个答案在最新的TS版本中不起作用,而且只适用于两个HOC,我需要编写更多。

我的tsconfig.json:

{
"compilerOptions": {
"allowJs": true,
"baseUrl": "./src",
"esModuleInterop": true,
"forceConsistentCasingInFileNames": true,
"isolatedModules": true,
"jsx": "preserve",
"lib": ["dom", "dom.iterable", "esnext"],
"module": "esnext",
"moduleResolution": "node",
"noEmit": true,
"resolveJsonModule": true,
"skipLibCheck": true,
"strict": true,
"target": "es5"
},
"exclude": ["node_modules"],
"include": ["next-env.d.ts", "**/*.ts", "**/*.tsx"]
}

CodeSandbox中的最小示例:https://codesandbox.io/s/hoc-breaking-example-mtp3m

如果你去rambdacompose键入,你会看到它是通用的,所以你可以定义结果函数,这样键入它可以删除错误

export default compose<React.FunctionComponent>(
withTitle("Hello StackOverflow!"),
connector
)(App);

最新更新