admin管理员组文章数量:1417107
The title will make more sense with an example:
I have the following component GlobalDialog:
export type GlobalDialogProps<T extends React.FunctionComponent<any>> = {
Trigger: React.FunctionComponent<{ onToggle: () => void; }>;
Panel: T;
panelProps: ComponentProps<T>;
zIndex: number;
};
export default function GlobalDialog<T extends React.FunctionComponent<any>>(props: GlobalDialogProps<T>) {
// Implementation details
}
and component FilterProductResultsControllerV2
export default function FilterProductResultsControllerV2<T extends React.FC<any>>(props: { ResultElement: T; propsFactory: (product: IProduct) => ComponentProps<T>; }) {
// Implementation details
}
I then try to pass FilterProductResultsControllerV2 as a Panel to my Global Dialog, and propsFactory ends up being inferred as (product: IProduct) => any instead of (product: IProduct) => CountTrackerProductProps
<GlobalDialog
zIndex={10}
Trigger={({ onToggle }) => (
// Implementation detail
)}
Panel={FilterProductResultsControllerV2}
panelProps={{
renderAs: "panel",
ResultElement: CountTrackerProduct,
propsFactory: (product) => {
const orderItemData = value[product.id];
return {
product: product,
onAdd: () => addOrderItem(product),
quantity: orderItemData?.quantity ?? null,
};
},
}}
/>
where CountTrackerProduct is:
type CountTrackerProductProps = { product: IProduct; onAdd: () => void; quantity: number | null; };
export default function CountTrackerProduct(props: CountTrackerProductProps) {
// Implementation details
}
A working solution to this problem is using FilterProductResultsControllerV2<typeof CountTrackerProduct> as Panel, but it's not the most elegant one either.
So my question is, why exactly does this happen in Typescript? and are there any ways around it, if any?
Full Sample Code that features the issue
import { useState } from "react";
interface IProduct {
id: string;
name: string;
}
type GlobalDialogProps<T extends React.FunctionComponent<any>> = {
Trigger: React.FunctionComponent<{ onToggle: () => void }>;
Panel: T;
panelProps: React.ComponentProps<T>;
zIndex: number;
};
function GlobalDialog<T extends React.FunctionComponent<any>>(props: GlobalDialogProps<T>) {
const [open, setOpen] = useState(false);
const { Panel, panelProps, Trigger } = props;
return (
<>
<Trigger onToggle={() => setOpen(!open)} />
{/*<Panel {...panelProps} /> */}
</>
);
}
function FilterProductResultsControllerV2<T extends React.FC<any>>(props: { ResultElement: T; propsFactory: (product: IProduct) => React.ComponentProps<T> }) {
return <div></div>;
}
type CountTrackerProductProps = {
product: IProduct;
onAdd: () => void;
quantity: number | null;
};
function CountTrackerProduct(props: CountTrackerProductProps) {
return <div></div>;
}
function OrderItemDataWidget() {
const [value, setValue] = useState<Record<IProduct["id"], { quantity: number }>>({});
const addOrderItem = (product: IProduct) => console.log(`added product ${product.id}`);
return (
<div>
<div>close off</div>
<GlobalDialog
zIndex={10}
Trigger={({ onToggle }) => <button onClick={onToggle} type="button">dummy</button>}
Panel={FilterProductResultsControllerV2}
panelProps={{
ResultElement: CountTrackerProduct,
propsFactory: (product) => {
const orderItemData = value[product.id];
return {
product: product,
onAdd: () => addOrderItem(product),
quantity: orderItemData?.quantity ?? null,
};
},
}}
/>
</div>
);
}
本文标签:
版权声明:本文标题:javascript - Getting TypeScript to Infer Props Correctly for a Nested Generic Function Component - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1745253332a2649952.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论