I am in possession of a shop that organizes a variety of types based on their IDs
interface Dog { type: "dog"; woofs: string; }
interface Cat { type: "cat"; meows: string; }
type Pet = Dog | Cat;
type AnimalState = Record<string, Pet>
My aim is to create a function that can output a specific pet type based on its key/ID.
function getSpecificAnimal(state: AnimalState, key: string, type: Pet["type"]) {
const pet = state[key];
if (pet.type === type) {
return pet;
}
throw new Error("pet was wrong type");
}
const aDog = getSpecificAnimal(state, "a", "dog"); // should return type Dog, or throw an exception
Unfortunately, I am struggling to instruct Typescript to narrow down the return value of the getSpecificAnimal
function.
I have experimented with generics and a type map to correlate all the arguments, but Typescript remains unsatisfied.
type PetTypeMap = {
dog: Dog,
cat: Cat,
}
function getAnimalOfType<T extends Pet, K extends T["type"]>(animals: AnimalState, id: string, type: K): PetTypeMap[K] {
const pet = animals[id];
// ^?
if (pet.type === type) {
return pet;
}
throw new Error("wrong pet type");
}
Despite my attempts, but to no avail. Am I unable to achieve this type of narrowing with Typescript?