type-fest
type-fest copied to clipboard
Add type for union joins
For example, this would be useful for a FontStyle
type where the possible values are the space separated string of the terms bold
, italic
, underline
, and strikethrough
.
Here a possibility, but it seems this could be improved.
import type { UnionToIntersection } from 'type-fest';
type UnionToOvlds<U> = UnionToIntersection<U extends unknown ? (f: U) => void : never>;
type PopUnion<U> = UnionToOvlds<U> extends (a: infer A) => void ? A : never;
type UnionConcat<U extends string, Sep extends string> = PopUnion<U> extends infer SELF
? SELF extends string
? Exclude<U, SELF> extends never
? SELF
: `${UnionConcat<Exclude<U, SELF>, Sep>}${Sep}${SELF}` | UnionConcat<Exclude<U, SELF>, Sep> | SELF
: never
: never;
type FontStyle = UnionConcat<'bold' | 'italic' | 'underline' | 'strikethrough', ' '>;
// "bold" | "italic" | "underline" | "strikethrough" | "bold italic" | "bold underline" |
// "italic underline" | "bold italic underline" | "bold strikethrough" | "italic strikethrough" |
// ... 4 more ... | "bold italic underline strikethrough"
Also, I'm unsure whether this should be considered a feature or not, but notice that "italic bold"
is not acceptable by this type because "bold italic"
is.
This could easily lead to infinite permutations. Not sure it's a good idea. It's also quite niche. I think we are more likely to add the underlying utilities that enable this, rather than this exact type (for example UnionConcat
).
In this specific case, it sounds like it's better to have the canonical value as a union and instead split the type of the user input into a union.
Yup. That's fair. Thanks!