Skip to content

Instantly share code, notes, and snippets.

@Lugriz
Created September 3, 2021 06:05
Show Gist options
  • Save Lugriz/da9c21a5794c96595c7dac5c01add2e1 to your computer and use it in GitHub Desktop.
Save Lugriz/da9c21a5794c96595c7dac5c01add2e1 to your computer and use it in GitHub Desktop.
Defining a type for email using template literal string and conditional types
type Alfa = 'a' | 'b' | 'c' | 'd'
| 'e' | 'f' | 'g' | 'h' | 'i'
| 'j' | 'k' | 'l' | 'm' | 'n'
| 'o' | 'p' | 'q' | 'r' | 's'
| 't' | 'u' | 'v' | 'w' | 'x'
| 'y' | 'z';
type Numeric = '1' | '2' | '3' | '4'
| '5' | '6' | '7' | '8' | '9';
type AllowedChars = '.' | Alfa | Numeric;
type Checker<T extends string, Check> = T extends `${infer CHAR}${infer REST}`
? CHAR extends Check ? Checker<REST, Check> : false
: true;
type Domain<P extends string> = P extends `${infer PROVIDER}.${infer DOMAIN}`
? Checker<PROVIDER, Alfa> extends true
? Checker<DOMAIN, Alfa> extends true ? true : false
: false
: false;
type Email<S extends string> = S extends `${infer MAIL}@${infer DOMAIN}`
? Checker<MAIL, AllowedChars> extends true
? Domain<DOMAIN> extends true ? S : never
: never
: never;
type Mail = Email<'[email protected]'>; // '[email protected]'
type BadMail = Email<'bad*[email protected]'>; // never
type BadMail2 = Email<'badmailmail.com'>; // never
type BadMail3 = Email<'badmail@m=ail.com'>; // never
type BadMail4 = Email<'badmail@mailcom'>; // never
type BadMail5 = Email<'[email protected]'>; // never
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment