Closed tarngerine closed 2 years ago
This sounds like a good idea @tarngerine but I actually don't know how to achieve this, would you be happy to raise a PR with the suggested changes? I'd be very happy to accept contributions.
I imagine it would look something like this?:
export type Tag<T = void> = T & {
label: string
value: string | number | symbol | null
}
export type TagSuggestion<T = void> = Tag<T> & Partial<TagMetaProps>
export type TagSelected<T = void> = Tag<T>
Here's a codesandbox with a minimal example with suggestions/suggestionTransform, where suggestionTransform
is getting the extended type provided via suggestions
https://codesandbox.io/s/pedantic-nash-c21wkm?file=/src/App.tsx
the general idea is that you specify <T extends Tag>
and use that + T
in the component, props, and any type that unions/extends the base type Tag
instead of Tag
itself
export type Tag = {
label: string;
value: string | number | symbol | null;
};
export type TagMetaProps = {
disabled: boolean;
};
// We use T instead of Tag here, the generic ensures it extends Tag
export type TagSuggestion<T extends Tag> = T & Partial<TagMetaProps>;
// The T is shared with other props
interface Props<T extends Tag> {
suggestions: TagSuggestion<T>[];
suggestionsTransform: (
value: string,
suggestions: TagSuggestion<T>[]
) => TagSuggestion<T>[];
}
// Lastly we have T extends Tag at the top component level since it needs to be provided to the Props type
export function ReactTags<T extends Tag>(props: Props<T>) {
return (
<>
Check the code editor to see if suggestionsTransform has the extended type
</>
);
}
I took a stab locally but it's turning out a bit non trivial due to some limitations of generic constraints, will poke around and see what i can do
Yea I might call this, it requires touching so much of the code it doesn't seem worth it. I'll push up a PR as a demo but I wasn't able to fully get it working — the type becomes overly constrained and I'm not sure when that happens/ don't have time to resolve it.
Thank you for your time and effort investigating @tarngerine, I really appreciate it and I've learned some things from your sample code. I've made a suggestion in the PR which I know will cover at least some cases but I'll continue to think about it.
I've exported the TagSelected
and TagSuggestion
types as part of the public interface for the component in d8c0f62cee2336985b53b40d2fda9b31dd73bbf8 and added some examples to the readme. I've tried this in a medium sized project and it works as expected.
Currently
Tag
is expected to have the keysvalue
andlabel
. I'd love to have Typescript recognize additional metadata that I supply with it, e.g. having thesuggestions
prop be typed as<T extends Tag>
?Thank you!