In TypeScript, I have certain values that are only necessary within the type system and not at runtime. I am seeking a way to void these values without losing their type information. The function bury
illustrated below is intended to replace the actual value with undefined and transform it into a tombstone representing the buried type. However, my current implementation of Tombstone
is inadequate because Tombstone<{ id: string }>
is equivalent to void
, which is also equal to Tombstone<{ id: number }>
. How can I effectively differentiate between buried values? My goal is to prevent confusion among developers and avoid unnecessary memory usage with values used solely for type validation.
type Tombstone<_A> = void
function bury<A>(_value: A): Tombstone<A> {
return undefined as Tombstone<A>
}
type Item = { id: number }
const correct: Tombstone<Item> = bury({ id: 123 })
const incorrect: Tombstone<Item> = bury({ id: 'abc' }) // <- should not work
type Special = Item & { meta: string }
const correct2: Tombstone<Item> = bury({ id: 123, meta: 'test' })
const correct3: Tombstone<Special> = bury({ id: 123, meta: 'test' })
const incorrect2: Tombstone<Special> = bury({ id: 123 }) // <- should not work