diff --git a/src/branded-strings.ts b/src/branded-strings.ts new file mode 100644 index 0000000..4b1afb9 --- /dev/null +++ b/src/branded-strings.ts @@ -0,0 +1,26 @@ +/** + * A branded string is a string that has a unique type, so that it can be + * distinguished from other strings. This is useful when you want to ensure + * that a string is only used in a specific context. When assigning to a + * branded string type it's not allowed to assign a non-branded string, or a + * string of the wrong brand: + * + * ```ts + * type Apple = BrandedString<"apple">; + * type Orange = BrandedString<"orange">; + * + * const apple: Apple = brandString("Pink Lady"); + * let orange: Orange = apple; // error! + * orange = "jalapeƱo"; // error! + * let justAString: string = apple; // This is ok + */ +export type BrandedString = string & { __brand: T }; + +/** + * Brands a string with the specified brand. + * + * @param s The string to brand. + */ +export function brandString(s: string): BrandedString { + return s as BrandedString; +} diff --git a/src/index.ts b/src/index.ts index 3be7892..cb045a6 100644 --- a/src/index.ts +++ b/src/index.ts @@ -176,3 +176,5 @@ export function exceptionToError(e: unknown): Error { } export { DefaultMap, ReadonlyDefaultMap } from "./default-map"; + +export { BrandedString, brandString } from "./branded-strings";