We read every piece of feedback, and take your input very seriously.
To see all available qualifiers, see our documentation.
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
interface Tagged { [UNIQUE_SYMBOL]: () => string } type Is<A, B> = (<G>() => G extends A ? 1 : 0) extends (<G>() => G extends B ? 1 : 0) ? true : false type Tagging<This, Tag extends string = string, NewTag extends Tagged = {[UNIQUE_SYMBOL]: (this: This) => Tag}> = true extends Is<This & NewTag, This> ? NewTag : ReturnType<<T extends This & NewTag>() => {[K in keyof T]: T[K]}> type ExtractTagged<B> = true extends Is<B, any> | Is<Extract<B, Tagged>, never> ? Tagging<B, ''> : ExtractOne<Extract<B, Tagged>> extends infer S extends Tagged ? S extends Tagging<infer This> ? true extends Is<Exclude<B, S | This>, never> ? S : S | ExtractTagged<Exclude<B, S | This>> : never /* infer X */ : never /* infer S */ type ExtractTags<B, I extends Tagged = ExtractTagged<B>, Tags = true extends Is<B, any> | Is<I, never> ? '' : I extends I ? ReturnType<I[US]> : never /* This extends I */> = true extends Is<Tags, ExtractOne<Tags>> ? Tags : '' type ExtractOne<U> = (U extends U ? (_: () => U) => void : never) extends (_: infer I extends () => U) => void ? ReturnType<I> : never type Split<Tags extends string> = Tags extends '' ? [] : Tags extends `${infer Tag} ${infer Rest}` ? Tag extends '' ? Split<Rest> : [Tag, ...Split<Rest>] : [Tags] type Join<Tags extends readonly string[]> = Tags extends [infer S extends string, ...infer R extends string[]] ? R extends [] ? S : `${S extends '' ? '' : `${S} `}${Join<R>}` : '' type Append<Tags extends string, T extends string> = string extends Tags ? T : Tags extends '' ? T : ` ${Tags} ` extends ` ${T} ` ? Tags : `${Tags} ${T}` type GetTags<B, Tags extends string = ExtractTags<B>> = true extends Is<Tags, never> ? [] : Split<Tags> type Tag<B, T extends string, I extends Tagged = ExtractTagged<B>> = true extends Is<I, never> ? B : I extends Tagging<infer This, infer Tags extends string> ? Tagging<This, Append<Tags, T>> extends infer NewTagged ? true extends Is<This | NewTagged, This> ? NewTagged : This | NewTagged : never /* infer NewI */ : never /* infer This, infer Tags */ type UnTag<B, I extends Tagged = ExtractTagged<B>> = true extends Is<I, never> ? B : I extends I ? I extends Tagging<infer This> ? This : never /* infer This */ : never /* I extends I */ type HasTag<B, T extends string, Tags extends string = ExtractTags<B>> = ` ${Tags} ` extends `${any} ${T} ${any}` ? true : false type HasTags<B, T extends readonly string[], Tags extends string = ExtractTags<B>> = ` ${Tags} ` extends `${any} ${Join<T>} ${any}` ? true : false type HasExactTags<B, T extends readonly string[], Tags extends string = ExtractTags<B>> = Tags extends Join<T> ? true : false
Playground
The text was updated successfully, but these errors were encountered:
No branches or pull requests
Playground
The text was updated successfully, but these errors were encountered: