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

remove our Join type once it's updated in ts-toolbelt #108

Open
github-actions bot opened this issue Oct 13, 2021 · 0 comments
Open

remove our Join type once it's updated in ts-toolbelt #108

github-actions bot opened this issue Oct 13, 2021 · 0 comments

Comments

@github-actions
Copy link

remove this once millsp/ts-toolbelt#255 is merged

see microsoft/TypeScript#46171

// TODO: remove this once https://github.com/millsp/ts-toolbelt/issues/255 is merged

    ? true
    : false

type _Join<T extends ReadonlyArray<unknown>, D extends string, Result extends string> = T extends []
    ? Result
    : T extends [Literal]
    ? `${Result}${T[0]}`
    : T extends [Literal, ...infer R]
    ? _Join<R, D, `${Result}${T[0]}${D}`>
    : string

/**
 * Concat many literals together
 *
 * like `ts-toolbelt`'s `Join` but tail-recursive, to allow for a higher stack depth in ts 4.5
 * @param T to concat
 * @param D to delimit
 * @see https://github.com/millsp/ts-toolbelt/issues/255
 */
// TODO: remove this once https://github.com/millsp/ts-toolbelt/issues/255 is merged
export type Join<T extends ReadonlyArray<Literal>, D extends string = ''> = _Join<
    T,
    D,
    ''
> extends infer X
    ? Cast<X, string>
    : never

/** a map of values where the keys are to be replaced by the values in {@link ReplaceValuesWithMap} */
type ReplaceValuesMap = Record<Exclude<AnyKey, symbol>, unknown>

type _TokenizeString<
    Value extends string,
    Map extends ReplaceValuesMap,
    Tokens extends string[]
> = '' extends Value
    ? Tokens
    : LongestString<MatchStart<Value, Keys<Map>>> extends infer Token
    ? Token extends string
        ? _TokenizeString<TrimStart<Value, Length<Token>>, Map, [...Tokens, Token]>
        : IndexOf<Value, Keys<Map>> extends infer NextTokenIndex
        ? NextTokenIndex extends -1
            ? [...Tokens, Value]
            : _TokenizeString<
                  TrimStart<Value, IndexOf<Value, Keys<Map>>>,
                  Map,
                  [
                      ...Tokens,
                      TrimEnd<
                          Value,
                          // intersection to work around https://github.com/microsoft/TypeScript/issues/43736
                          NextTokenIndex & number
                      >,
                  ]
              >
        : never
    : never

type _ReplaceValuesWithMap<
    InputTokens extends string[],
    Map extends ReplaceValuesMap,
    OutputTokens // extends string[] (handled in the conditional type below instead to work around https://github.com/microsoft/TypeScript/issues/46171)
> = string[] extends InputTokens
    ? InputTokens
    : InputTokens extends []
    ? OutputTokens
    : _ReplaceValuesWithMap<
          ArrayTail<InputTokens>,
          Map,
          [
              ...(OutputTokens extends string[] ? OutputTokens : never),
              ArrayHead<InputTokens> extends Keys<Map>
                  ? Map[ArrayHead<InputTokens>]
                  : ArrayHead<InputTokens>,
          ]
      >

/**
 * replaces all instances in `Value` of the first string with the second string with each tuple in `Map`
 * @example
 * type Foo = ReplaceValuesWithMap<'foobarbaz', {foo: 'bar', baz: 'qux'}> // "barbarqux"
 */
export type ReplaceValuesWithMap<Format extends string, Map extends ReplaceValuesMap> = Join<
    // need to narrow the generics using these conditional types because the compiler fails to
    //  see https://github.com/microsoft/TypeScript/issues/46171
    _ReplaceValuesWithMap<
        _TokenizeString<Format, Map, []> extends infer Tokens
            ? Tokens extends string[]
                ? Tokens
                : never
            : never,
        Map,
        []
    > extends infer Strings
        ? Strings extends ReadonlyArray<Literal>
            ? Strings
            : never
        : never
>

/**
 * a stringified version of {@link Enumerate}

2d7431763e482c388618c15576d779eb52bf0e7b

@github-actions github-actions bot added the todo label Oct 13, 2021
@DetachHead DetachHead changed the title remove this once https://github.com/millsp/ts-toolbelt/issues/255 is merged remove out Join type once it's updated in ts-toolbelt Jan 28, 2022
@DetachHead DetachHead changed the title remove out Join type once it's updated in ts-toolbelt remove our Join type once it's updated in ts-toolbelt Jan 28, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant