Reputation: 98
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
Reputation: 371019
With template literal types, you can validate that a string either:
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