Here is the example which shows what I want to achieve. It almost works except 2 problems:
- Set does not show an error on incorrect code
- Immer Draft type (or any DeepWritable utility type) completely messes up this trick
Basically it seems to me that what I am doing here isn't really a thing. So the question is: is there some other way to do the same thing?
type Opaque<Type, Token = unknown> = Type & {
readonly __opaque__: Token
}
type AnimalId = CatId | DogId
type Animal = Cat | Dog
type CatId = Opaque<number, Cat>
type Cat = {
readonly kind: 'Cat'
readonly id: CatId
}
type DogId = Opaque<number, Dog>
type Dog = {
readonly kind: 'Dog'
readonly id: DogId
}
const cat: Cat = {
kind: 'Cat',
id: 1 as CatId,
}
const dog: Dog = {
kind: 'Dog',
id: -1 as DogId,
}
const animals: Map<CatId, Cat> & Map<DogId, Dog> & Map<AnimalId, Animal> = new Map()
animals.set(cat.id, cat) // no error should be here
animals.set(cat.id, dog) // wanna see error here
const test1: Cat | undefined = animals.get(cat.id) // no error should be here
const test2: Dog | undefined = animals.get(dog.id) // no error should be here
const test4: Animal | undefined = animals.get(1 as AnimalId) // no error should be here
const test3 = animals.get(3) // wanna see error here