Skip to content

Instantly share code, notes, and snippets.

@ArtemAvramenko
Last active August 7, 2024 19:34
Show Gist options
  • Save ArtemAvramenko/325b35472203619e1bb446af64ad79c2 to your computer and use it in GitHub Desktop.
Save ArtemAvramenko/325b35472203619e1bb446af64ad79c2 to your computer and use it in GitHub Desktop.
Regex-validated strings in TypeScript
const isDevMode = () => true;
type ValidatedString<T extends string> = string & {
[K in keyof string] : K extends `as${string}String` ? never : string[K]
} & {
readonly __format: T
};
/*
eslint-disable
@typescript-eslint/no-explicit-any, @typescript-eslint/ban-types,
@typescript-eslint/unbound-method, @typescript-eslint/no-unsafe-assignment,
@typescript-eslint/no-unsafe-member-access
*/
function addStringCheckMethod(
checkMethod: keyof string & `as${string}String`,
regExp: RegExp) {
(String.prototype as any)[checkMethod] = String.prototype.valueOf;
if (isDevMode()) {
(String.prototype as any)[checkMethod] = function (this: String) {
if (regExp.test(this as string)) {
return this.valueOf();
}
throw Error(`'${this}' failed the ${checkMethod} check`);
};
}
}
/* eslint-enable */
/** UTC date string (2000-12-31T12:00:00.000Z) */
type UtcDateString = ValidatedString<'UTC Date'>;
declare interface String { asUtcDateString(): UtcDateString; }
addStringCheckMethod('asUtcDateString', /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(?:.\d{1,3})?Z$/);
/** Local date string (2000-12-31T08:00:00.000) */
type LocalDateString = ValidatedString<'Local Date'>;
declare interface String { asLocalDateString(): LocalDateString; }
addStringCheckMethod('asLocalDateString', /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(?:.\d{1,3})?$/);
/** HEX color string (#BB3355) */
type HexColorString = ValidatedString<'Hex Color'>;
declare interface String { asHexColorString(): HexColorString; }
addStringCheckMethod('asHexColorString', /^#[0-9a-f]{6}$/i);
// type: HexColorString extends string
let color = '#bbccdd'.asHexColorString();
// type: UtcDateString extends string
let utcDate = '2000-12-31T12:00:00.000Z'.asUtcDateString();
// type: LocalDateString extends string
let localDate = '2000-12-31T08:00:00.000'.asLocalDateString();
const s: string = localDate;
// tsc error: Type '"Local Date"' is not assignable to type '"UTC Date"'
utcDate = localDate;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment