Skip to content

Instantly share code, notes, and snippets.

@dmmulroy
Created September 13, 2023 20:35
Show Gist options
  • Save dmmulroy/358f0ebf27970bbe1956ab76724e7604 to your computer and use it in GitHub Desktop.
Save dmmulroy/358f0ebf27970bbe1956ab76724e7604 to your computer and use it in GitHub Desktop.
declare const BRAND: unique symbol
/**
* Creates a new branded type by intersecting a given type with an object
* containing a unique brand symbol.
*/
export type Brand<T, B> = T & { [BRAND]: B }
/** Creates a new branded type by intersecting a given type with an object containing a unique brand symbol. */
export function toBrandedType<T, B>(value: T, _brand: B): Brand<T, B> {
return value as Brand<T, B>
}
type TodoId = Brand<string, 'TodoId'>
type Todo = Readonly<{
id: TodoId
title: string
status: 'todo' | 'in_progress' | 'done'
}>
const TODO_SCHEMA = z
.object({
id: z.string(),
title: z.string(),
status: z.enum(['todo', 'in_progress', 'done']),
})
.transform<Todo>((parsed) => ({
id: toBrandedType(parsed.id, 'TodoId'),
title: parsed.title,
status: parsed.status,
}))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment