TS ascii art

TypeScript ASCII Art!

a minute read

Typehero - advent of typescript solution for day 20!


Day 20 of the typehero advent of code involved converting regular strings to ascii art.

This is My Solution for day 20

The Problem

Dummy
type ToAsciiArt<T> = any;

type test_0_actual = ToAsciiArt<"   * : * Merry * : *   \n  Christmas  ">;

type test_0_expected = [
  "░░░░░#░░░█▄░▄█ █▀▀ █▀█ █▀█ █ █ ░░░#░░░░░",
  "░░░#░░░#░█ ▀ █ █▀▀ ██▀ ██▀ ▀█▀ ░#░░░#░░░",
  "░░░░░#░░░▀ ░░▀ ▀▀▀ ▀ ▀ ▀ ▀ ░▀ ░░░░#░░░░░",
  "░░█▀▀ █ █ █▀█ █ █▀▀ ▀█▀ █▄░▄█ █▀█ █▀▀ ░░",
  "░░█ ░░█▀█ ██▀ █ ▀▀█ ░█ ░█ ▀ █ █▀█ ▀▀█ ░░",
  "░░▀▀▀ ▀ ▀ ▀ ▀ ▀ ▀▀▀ ░▀ ░▀ ░░▀ ▀ ▀ ▀▀▀ ░░",
];

Meaning you would need to convert test_0_actual to test_0_expected

the letters are already provided to you in a record with the type signature of Record<string, [string, string, string]> which has

  • key - string to be converted
  • value - top, middle and bottom of the ascii version of the key

The Idea

This is a complicated type that requires a few utility types to work

  1. Generate - accepts a string and uses it to create a tuple containing the corresponding Letters tuples
  2. GetIndex - accepts a a tuple of Letters tuples and gets a specific index in the tuple
  3. Join - accepts a tuple of Letters tuples and adds them to each other based on their index
  4. ToAsciiArt - the final type which wraps up all the other types and is used by the typehero challenge

Solution

Random Code
type Letters = {
  A: [
    '█▀█ ',
    '█▀█ ',
    '▀ ▀ ',
  ],
  B: [
    '█▀▄ ',
    '█▀▄ ',
    '▀▀  '
  ],
  C: [
    '█▀▀ ',
    '█ ░░',
    '▀▀▀ '
  ],
  E: [
    '█▀▀ ',
    '█▀▀ ',
    '▀▀▀ '
  ],
  H: [
    '█ █ ',
    '█▀█ ',
    '▀ ▀ '
  ],
  I: [
    '',
    '',
    ''
  ],
  M: [
    '█▄░▄█ ',
    '█ ▀ █ ',
    '▀ ░░▀ '
  ],
  N: [
    '█▄░█ ',
    '█ ▀█ ',
    '▀ ░▀ '
  ],
  P: [
    '█▀█ ',
    '█▀▀ ',
    '▀ ░░'
  ],
  R: [
    '█▀█ ',
    '██▀ ',
    '▀ ▀ '
  ],
  S: [
    '█▀▀ ',
    '▀▀█ ',
    '▀▀▀ '
  ],
  T: [
    '▀█▀ ',
    '░█ ░',
    '░▀ ░'
  ],
  Y: [
    '█ █ ',
    '▀█▀ ',
    '░▀ ░'
  ],
  W: [
    '█ ░░█ ',
    '█▄▀▄█ ',
    '▀ ░ ▀ '
  ],
  ' ': [
    '',
    '',
    ''
  ],
  ':': [
    '#',
    '',
    '#'
  ],
  '*': [
    '',
    '#',
    ''
  ],
};

type GetIndex<T, N extends number, R extends string = ""> = T extends [
	infer F extends [string, string, string],
	...infer L,
]
	? GetIndex<L, N, `${R}${F[N]}`>
	: R;

type Join<T extends any[], R extends any[] = []> = R["length"] extends 3
	? R
	: Join<T, [...R, GetIndex<T, R["length"]>]>;

type Generate<V extends string, R extends any[] = []> = Uppercase<V> extends `${infer F extends
	keyof Letters}${infer L}`
	? Generate<L, [...R, Letters[F]]>
	: R;

type ToAsciiArt<T extends string, R extends any[] = []> = T extends `${infer F}\n${infer L}`
	? ToAsciiArt<L, [...R, ...Join<Generate<F>>]>
	: [...R, ...Join<Generate<T>>];