Skip to content

A library to help make runtime-validated strings, but using branded types to preserve a modicum of type-safety and convenience at build-time.

Notifications You must be signed in to change notification settings

axhxrx/validated-string

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

17 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

@axhxrx/validated-strings

A library to help make runtime-validated strings, but using branded types to preserve a modicum of type-safety and convenience at build-time.

Intended for specialized string types that are too complex to be modeled within the type system itself, e.g. "starts with an alphanumeric character and less than 1000 characters long, with at least three swear words", or "three words in German, separated by spaces", etc.

Example:

// Define a validator function:
const isCowName = (s: string) => [
  'Bessie',
  'Daisy',
  'Elsie',
  'Flora',
  'Hedda',
].includes(s);

// Use the validator to create a new factory and type, and give them the same name:
const { factory, type } = ValidatedString.create(isCowName);
export const CowName = factory;
export type CowName = typeof type;

// Now, we can use `CowName` in both contexts:
const x = CowName.try('Bessie'); // x is 'Bessie'
const y: CowName | undefined = CowName.try('not a cow name'); // y is undefined
const z: CowName = CowName.assert('Bessie'); // z is 'Bessie'
const ohFuck = CowName.assert('not a cow name'); // throws an error

That's useful when you want to worry about the validation only in one spot, and lean on the type system elsewhere. E.g.:

// Here, we will get a build-time error if we try to just use some un-checked `string` instead of a validated `CowName`:
function callCow(cowName: CowName)
{
  const audio = TextToSpeech.getAudio(`Hey, ${cowName}! Come on home!`);
  while (!Barn.contains(cowName))
  {
    LoudSpeaker.play(audio);
    sleep(10);
  }
}

// Meanwhile, on the other side of town...

class FarmOperatorConsole
{
  validateAndCallCow()
  {
    console.log('Enter the cow name you wish to call:');
    const cowName = getOperatorInput(); // string

    const validatedCowName = CowName.try(cowName);
    if (validatedCowName)
    {
      // Once we've done the validation here at the boundary of our system, the rest of the internals can just use `CowName` instead of `string`, and not worry about validation.
      callCow(validatedCowName);
    }
    else
    {
      console.log('Invalid cow name. Please try again.');
      this.validateAndCallCow();
    }
  }
}

License

MIT or WTFPL, your choice.

About

A library to help make runtime-validated strings, but using branded types to preserve a modicum of type-safety and convenience at build-time.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published