Laurenz1606
Laurenz1606

Reputation: 98

Typescript Type: Only allow certain characters (Brainfuck)

I am writing a Brainfuck interpreter (more of an executer) in Typescript, now i want to Validate my Input like this:

type BrainfuckCode = /* The magic type that only allows <>+-.,[] */

const input1: BrainfuckCode = "+++++++>"
//here shouldn't be an error

const input2: BrainfuckCode = "+++++++>INVALID CHARACTERS"
//here should be an error

Is there a way to write a type like this? The string length will vary, which means it can not be hardcoded. So far i've come up with this:

type BrainfuckCode = "<" | ">" | "+" | "-" | "." | "," | "[" | "]"

Upvotes: 0

Views: 1902

Answers (1)

CertainPerformance
CertainPerformance

Reputation: 371019

With template literal types, you can validate that a string either:

  • is composed of exactly one valid character, or
  • starts with one valid character, and the rest of the string matches the pattern recursively
type BFChar = "<" | ">" | "+" | "-" | "." | "," | "[" | "]"
type IsBF<T extends string> = T extends BFChar
    ? T
    : T extends `${BFChar}${infer R}`
        ? IsBF<R>
        : never;

const badCode = '<<foo';
type badIsValid = IsBF<typeof badCode>; // never

const goodCode = '<<';
type goodIsValid = IsBF<typeof goodCode>; // not never

Note that this will only work for strings present in source code, eg

const theString = '...';

It will not be able to do anything with dynamically generated strings (such as those from user input) because those will only be typed as string - types (and type verification) only exists in the pre-compiled code, not in the generated JavaScript.

To validate strings that are put in the source code itself, this approach will work, but otherwise, you'll have to implement the validator in JavaScript.

Upvotes: 1

Related Questions