簡體   English   中英

TypeScript/React - 如何讓 function 接受通用組件類型?

[英]TypeScript/React - How to have function accept a generic component type?

我現在正在使用 React/TypeScript。 在編寫單元測試時,我很喜歡可重用的設置邏輯。 諸如使用 React 測試庫渲染我的 React 組件之類的事情,我每次都必須這樣做,我想要一個 function 為我做這件事。 基本上我傳入了我的 React 組件和其他一些 arguments,它完成了所有的設置邏輯。 這是我現在所擁有的:

import React, { ComponentType } from 'react';
import { createMemoryHistory, MemoryHistory } from 'history';
import { createStore, RootState } from '../../../src/store';
import { EnhancedStore } from '@reduxjs/toolkit';
import { render, waitFor } from '@testing-library/react';
import { Provider } from 'react-redux';
import { Router } from 'react-router';

export interface RenderConfig<T> {
    component: ComponentType<T>;
    props?: T;
    reduxState?: Partial<RootState>;
}

export interface RenderResult {
    store: EnhancedStore<RootState>;
    history: MemoryHistory;
}

const renderComponent = async <T extends object>(config: RenderConfig<T>): Promise<RenderResult> => {
    const store = createStore(config.reduxState ?? {});
    const history = createMemoryHistory();
    const CompToRender = config.component;
    await waitFor(() =>
        render(
            <Provider store={store}>
                <Router history={history}>
                    <CompToRender { ...(config.props ?? {}) } />
                </Router>
            </Provider>
        )
    );
    return {
        store,
        history
    };
};

export default renderComponent;

如您所見,renderComponent function 接受一個配置參數。 這會聯系組件 prop,即 ComponentType,以及可選的 Props 參數。 我希望道具與 ComponentTypes 泛型參數具有相同的泛型類型。

但是,當我這樣做時,我會收到此錯誤:

TS2322:類型“{}”不可分配給類型“T”。 “{}”可分配給“T”類型的約束,但“T”可以用約束“對象”的不同子類型來實例化。

我知道 {} 是 ComponentType 的泛型類型參數的默認類型。 我只是不明白如何使這個邏輯起作用。

“問題”是 config.props 是可選的,而組件可能需要一些道具。

我設法重新創建了這個問題,然后通過從道具中刪除可選類型並在沒有道具的情況下刪除空的 object 來解決它。

沙盒鏈接

這個想法是 ComponentType 中的 T 非常真實,並且可能需要將一些 props 傳遞給組件,因此您不能將 props 設為可選或為它提供空的 object,因為它可能需要 props。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM