30970-medium-shitariteraru

Back

type IsUnion<T, U = T> = [T] extends [never]
  ? false
  : T extends T
  ? [U] extends [T]
    ? false
    : true
  : never;

type IsFixedStringLiteralType<S extends string> = IsUnion<S> extends true
  ? false
  : { [P: string]: unknown } extends {
      [P in S]: unknown;
    }
  ? false
  : true;

Solution by yukicountry #34493

type IsFixedStringLiteralType<S extends string> = {} extends Record<S, 1> ? false : Equal<[S], S extends unknown ? [S] : never>

Solution by ahmed-omegup #33984

type IsNumOrBool<S extends string> = S extends `${infer _ extends number}${any}` ? true :
  S extends `${infer _ extends bigint}${any}` ? true :
    S extends `${infer F extends boolean}${any}` ? F extends true | false ? false : true : false

type IsConst<S extends string> = S extends '' ? true :
  IsNumOrBool<S> extends false ? S extends `${infer F}${infer Rest}` ? string extends F ?  false : `${string & {}}` extends F ? false : IsConst<Rest> : false : false

type IsUnion<S extends string, T = S> = S extends T ? [T] extends [S] ? false : true : never

type IsFixedStringLiteralType<S extends string> = [S] extends [never] ? false : IsUnion<S> extends false ? IsConst<S> : false

Solution by moonshadow-miao #33926

// to determine if a string S is a definite string literal type.
type IsFixedStringLiteralType<S> = [S] extends [AsUnion<S> | AsWildcard<S>] ? false : true

// to determine if S is a union type or should evaluate to never
type AsUnion<S, U = S> = U extends U ? Exclude<S, U> : U

// to check for embedded wildcards in S or should evaluate to never
type AsWildcard<S>
  = S extends `${WildcardConstraint<infer _>}${any}` ? S
  : S extends `${any}${infer R}` ? [AsWildcard<R>] extends [never] ? never : S
  : S extends '' ? never : S // if the string is not empty but does not match the initial template split

// To match a wildcard `${number}`, `${string}`, etc
type WildcardConstraint<C extends string> = `${any}` extends C ? C : never

Playground

Solution by teamchong #32985

// your answers
import type { Equal, NotEqual } from '@type-challenges/utils'

type IsNever<T> = [T] extends [never] ? true : false;
type IsUnion<T> = NotEqual<[T] & T, (T extends T ? [T] : never) & T>;

type IsFixedStringLiteralType<S extends string> = true extends
  | IsNever<S>
  | IsUnion<S>
  | Equal<S, string>
  ? false
  : S extends `${infer First}${infer Rest}`
    ? true extends
      | Equal<First, string>
      | Equal<First, `${string & {}}`>
      | Equal<First, `${number}`>
      | Equal<First, `${number & {}}`>
      | Equal<First, `${bigint}`>
      | Equal<First, `${bigint & {}}`>
      | Equal<First, `${any}`>
      ? false
      : IsFixedStringLiteralType<Rest>
    : true;

Solution by wubrafiq807 #32614

type IsUnion<T, U = T> = [T] extends [never] ? false : T extends T ? [U] extends [T] ? false : true : false

type IsEmbedded<T> = Equal<T, string> extends true
  ? true
  : Equal<T, `${bigint}`> extends true
    ? true
    : Equal<T, `${number}`> extends true
      ? true
      : Equal<T, `${boolean}`> extends true
        ? true
        : Equal<T, `${string & {}}`> extends true // Additional, `${number & {}}` etc.
          ? true
          : false

type IsFixedStringLiteralType<S extends string> =
  [S] extends [never]
    ? false // 1. never type
    : IsUnion<S> extends true
      ? false // 2. union
      : S extends `${infer F}${ infer Rest extends string}`
        ? IsEmbedded<F> extends true // 3. embedded types
          ? false
          : Rest extends ''
            ? true
            : IsFixedStringLiteralType<Rest>
        : false

Solution by lvjiaxuan #31978

type SingleCheck<S> = S extends ''
  ? true
  : S extends `${infer C}${infer T}`
    ? '0' | '1' extends C
      ? false
      : SingleCheck<T>
    : false;

type IsFixedStringLiteralType<S extends string, T = S> = [S] extends [never]
  ? false
  : S extends unknown
    ? [T] extends [S]
      ? SingleCheck<S>
      : false
    : false;

Solution by alexandroppolus #31666

import type { Equal, NotEqual } from '@type-challenges/utils'

type IsNever<T> = [T] extends [never] ? true : false;
type IsUnion<T> = NotEqual<[T] & T, (T extends T ? [T] : never) & T>;

type IsFixedStringLiteralType<S extends string> = true extends
  | IsNever<S>
  | IsUnion<S>
  | Equal<S, string>
  ? false
  : S extends `${infer First}${infer Rest}`
    ? true extends
      | Equal<First, string>
      | Equal<First, `${string & {}}`>
      | Equal<First, `${number}`>
      | Equal<First, `${number & {}}`>
      | Equal<First, `${bigint}`>
      | Equal<First, `${bigint & {}}`>
      | Equal<First, `${any}`>
      ? false
      : IsFixedStringLiteralType<Rest>
    : true;

Playground

Solution by sugoroku-y #31481