Last active
August 7, 2024 19:34
-
-
Save ArtemAvramenko/325b35472203619e1bb446af64ad79c2 to your computer and use it in GitHub Desktop.
Regex-validated strings in TypeScript
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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