Spaces:
Sleeping
Sleeping
File size: 974 Bytes
05c5ed5 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 | /**
* @module tagged-types
* Minimal runtime type checking with discriminated unions
*/
const DEFAULT_KEY = "__$ref__" as const;
export type Tagged<TTag extends string, TData> = TData & {
[DEFAULT_KEY]: TTag;
};
class TagBuilder<TData, TTag extends string> {
constructor(private tagValue: TTag) {}
isMaybe = (value: unknown): value is Tagged<TTag, TData> => {
return (
value !== null &&
value !== undefined &&
typeof value === "object" &&
DEFAULT_KEY in value &&
(value as any)[DEFAULT_KEY] === this.tagValue
);
};
create = (data: TData): Tagged<TTag, TData> => {
return {
...data,
[DEFAULT_KEY]: this.tagValue,
} as Tagged<TTag, TData>;
};
unwrap = (value: Tagged<TTag, TData>): TData => {
const { [DEFAULT_KEY]: _, ...data } = value;
return data as TData;
};
}
export function tag<TData>(tagName: string) {
return Object.freeze(new TagBuilder<TData, typeof tagName>(tagName));
}
|