Skip to content
New issue

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

697 - Tag #16642

Open
justBadProgrammer opened this issue Sep 24, 2022 · 0 comments
Open

697 - Tag #16642

justBadProgrammer opened this issue Sep 24, 2022 · 0 comments
Labels
697 answer Share answers/solutions to a question en in English

Comments

@justBadProgrammer
Copy link

justBadProgrammer commented Sep 24, 2022

// your answers
type IsEqual<X,Y> =(<A>()=>A extends X ? 1 : 2) extends 
    (<B>()=>B extends Y ? 1 : 2)
    ? true
    : false ;

declare const a:unique symbol;
type Unique =typeof a;

declare const d: unique symbol;
type CommonValue=typeof d;

declare const b:unique symbol;
type NonRegular = typeof b;

type GetTagValue<
    Source> =
    Unique extends keyof Source
    ? Exclude<keyof Exclude<Source[Unique],undefined>,symbol|number>
    : never ;

type TagValueFromTagTuple<
    T extends readonly string[],
    TagValue extends string = never,
    PossiblyEmptyValue extends string = [TagValue] extends [never] ? '' : TagValue> =
    T extends readonly [infer R extends string,...infer U extends readonly string[]]
    ? U extends []
    ? TagValueFromTagTuple<U,`${PossiblyEmptyValue}${R}`>
    : TagValueFromTagTuple<U,`${PossiblyEmptyValue}${R}|`>
    : TagValue  ;

type TagTupleFromTagValue<
    TagValue extends string> =
    [TagValue] extends [never]
    ? []
    : TagValue extends `${infer R extends string}|${infer U extends string}`
    ? [R,...TagTupleFromTagValue<U>]
    : [TagValue] ;

type GetTags<
    Source> =
     [Source] extends [never] 
    ? []
    : 1 extends 2&Source
    ? []
    : TagTupleFromTagValue<GetTagValue<Source>> ;

type SetMarker<
    Source,
    NewTagValue extends string,
    OldTagValue extends string = 
        GetTagValue<Source>,
    TagValue extends string  = 
        [OldTagValue] extends [never] 
        ? `${NewTagValue}`
        : `${OldTagValue}|${NewTagValue}` ,
    Marker extends object = {[J in Unique]? : {[J in TagValue|CommonValue]? : true}}   > =
    NonRegular extends keyof Source  
    ? {[J in NonRegular] : Source[J]}&Marker
    : UnTag<Source>&Marker  ;      

type EffectiveSource<
    Source,
    > =
    [IsEqual<Source,{}>&IsEqual<Source,never>&IsEqual<Source,any>] extends [never] 
    ? {[J in NonRegular] : Source}
    : Source  ;
    
type Tag<
    Source, 
    NewTagValue extends string,
    > =
    IsEqual<Source,undefined>&IsEqual<Source,null> extends [never]
    ? Source
    : SetMarker<EffectiveSource<Source>,NewTagValue>  ;

type UnTag<
    Source,
    Marker ={[J in Unique&keyof Source]? :Source[J]}> =
    NonRegular extends keyof Source
    ? Source[NonRegular]
    : Source extends infer R&Marker
    ? R
    : Source  ;

type UnionMemberHasTag<
    Source, 
    TagValue extends string> =     
    Source extends Source
    ? [GetTagValue<Source>] extends [never]
    ? false
    : GetTagValue<Source> extends `${infer R}${TagValue}${infer U}`
    ? true
    : false
    : never;

type UnionMemberHasExactTag<
    Source,
    TagValue extends string> =
    Source extends Source
    ? IsEqual<GetTagValue<Source>,TagValue>
    : never ;

type HasTag<
    Source,
    TagValue extends string> = 
    UnionMemberHasTag<Source,TagValue> extends true 
    ? true 
    : false ;

type HasTags<
    Source, 
    TagTuple extends readonly string[]> =
    HasTag<Source,TagValueFromTagTuple<TagTuple>> ;

type HasExactTags<
    Source, 
    TagTuple extends readonly string[]> =
    TagTuple extends []
    ? true 
    : UnionMemberHasExactTag<Source,TagValueFromTagTuple<TagTuple>> extends true 
    ? true
    : false ;
@justBadProgrammer justBadProgrammer added answer Share answers/solutions to a question en in English labels Sep 24, 2022
@github-actions github-actions bot added the 697 label Sep 24, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
697 answer Share answers/solutions to a question en in English
Projects
None yet
Development

No branches or pull requests

1 participant