Improve typing for `component` prop in components that accept it
I spent... some time trying to parse it
I don't think this does what you intended to do
keyof T is properties of a string in case of T being a tagname. Or it's never if you pass typeof Component.
So copilot is wrong by saying keyof T includes all component prop keys. But it doesn't contain anything useful either.
I believe you do want to use keyof GridContainerProps<T> instead of keyof T here
Originally posted by @ariser in https://github.com/ClickHouse/click-ui/pull/663#discussion_r2303876935
Elaborating on the comment.
Current typing, for example in GridContainer:
type GridContainerPolymorphicComponent = <T extends ElementType = "div">(
props: Omit<ComponentProps<T>, keyof T> & GridContainerProps<T>
) => ReactNode;
The issue with this, is that Omit<ComponentProps<T>, keyof T> doesn't seem to make sense.
Examples:
If I use a user-defined component, keyof T resolves to never:
If I use an HTML tag as a component, keyof T resolves to members of a String instance:
it doesn't make sense to exclude either of these options from ComponentProps<T>, it does nothing. Something clearly doesn't work as intended.
So we need to
- clarify the intention behind these typings
- fix them, taking into account current behavior that I described
chunk of code I used to verify how these types behave, in case someone needs it
function Example<T extends ElementType>(
component: T,
fn: (keysof: keyof T, props: Omit<ComponentProps<T>, keyof T>) => void
) {}
Example(Text, (keysof, props) => {
keysof;
props;
});
Example("div", (keysof, props) => {
keysof;
props;
});
Components that use this pattern for types (including, but not limited to)
- Text
- GridContainer
- Container