[英]Passing implementations of generic types to React component props
我正在研究TypeScript / React項目,我們正在為多步過程構建一個通用的“向導”組件。 該向導是一個包裝器,它接受“面板”組件屬性的數組,並通過IWizardPanelProps接口向每個組件公開導航邏輯。
向導組件和面板界面的實現如下:
export interface IWizardPanelProps {
changePanel: (increment: number) => void;
}
export class WizardPanel<T> extends React.Component<IWizardPanelProps & T>{
constructor(props: IWizardPanelProps & T) {
super(props);
}
}
interface IWizardProps {
panelComponents: (typeof WizardPanel)[],
showControls?: boolean // Hidden by default - assumes panels themselves handle pagination
}
interface IWizardState {
panelIndex: number
}
export class Wizard extends React.Component<IWizardProps, IWizardState> {
constructor(props: IWizardProps) {
super(props);
this.state = {
panelIndex: 0
}
}
changePanel = (increment: number) => {
const newIndex = this.state.panelIndex + increment;
this.setState({ panelIndex: newIndex });
};
render() {
const { panelComponents, showControls } = this.props;
return (
<div>
<p><strong>Ye olde Wizard Component! (This is a placeholder, but the functionality is mostly there)</strong></p>
{panelComponents.map((Panel, key) => (
<div className={key === this.state.panelIndex ? undefined : 'hidden'} key={key}>{<Panel {...this.props} changePanel={this.changePanel}></Panel>}</div>
))}
{showControls && <div>
<button disabled={this.state.panelIndex === 0} onClick={() => this.changePanel(-1)}>
Previous
</button>
<button disabled={this.state.panelIndex === panelComponents.length - 1} onClick={() => this.changePanel(1)}>
Next
</button>
</div>}
</div>
);
}
}
然后,當我們創建面板組件時,我們會像這樣:
interface IMyPanelProps {
...
}
export class MyPanel extends WizardPanel<IMyPanelProps> {
constructor(props: IWizardPanelProps & IMyPanelProps) {
super(props);
}
render() {
...
}
...
}
到目前為止還好嗎?
但是,當我們去實現這樣的向導時:
<Wizard panelComponents={[ MyPanel ]}></Wizard>
我們收到以下錯誤:
類型'(typeof MyPanel)[]'不能分配給類型'(typeof WizardPanel)[]'。
類型'typeof MyPanel'不能分配給類型'typeof WizardPanel'。
類型“ MyPanel”不可分配給類型“ WizardPanel”。
屬性“ props”的類型不兼容。
輸入'Readonly <{children ?: ReactNode; }>&Readonly <IWizardPanelProps&IMyPanelProps>'不可分配為類型'Readonly <{children ?: ReactNode; }>和Readonly <IWizardPanelProps&T>'。
輸入'Readonly <{children ?: ReactNode; }>&Readonly <IWizardPanelProps&IMyPanelProps>”不能分配為類型“ Readonly <IWizardPanelProps&T>”。
是什么賦予了? 似乎可以歸結到最后一行:
Readonly<{ children?: ReactNode; }> & Readonly< IWizardPanelProps & IMyPanelProps>' is not assignable to type 'Readonly< IWizardPanelProps & T>
但我不明白自己做錯了什么。 我們如何錯過Readonly<{ children?: ReactNode; }>
Readonly<{ children?: ReactNode; }>
在propComponents的IWizardProps聲明中?
您可以使用React.ComponentType
類型。 這是定義組件類型的預期方式。
interface IWizardProps {
panelComponents: React.ComponentType<IWizardPanelProps>)[],
showControls?: boolean
}
問題在於WizardPanel
是泛型的,而分配的類卻不是,這會導致類型之間的不兼容。 例如,這也可以工作:
export class BasicWizardPanel extends WizardPanel<{}>{}
interface IWizardProps {
panelComponents: (typeof BasicWizardPanel)[],
showControls?: boolean // Hidden by default - assumes panels themselves handle pagination
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.