mapis
v2.0.0
Published
Utility function to map a value to a function
Downloads
906
Maintainers
Readme
mapis
The mapis
utility function is used to map a value to a corresponding function based on the type of the value.
To illustrate better how it works imagine we had the following types:
interface Person<T extends Pet> {
pet: T;
}
type Pet = Dog | Cat;
interface Dog {
meta: { type: "dog" };
data: { name: string };
}
interface Cat {
meta: { type: "cat" };
data: { name: string };
}
If we wanted to create a function called info
that receives a person as
argument and returns different data depending on the pet that the person has we
could use the mapis
function the following way:
import { mapis } from "mapis";
interface Person<T extends Pet> {
pet: T;
}
type Pet = Dog | Cat;
interface Dog {
meta: { type: "dog" };
data: { name: string };
}
interface Cat {
meta: { type: "cat" };
data: { name: string };
}
const func = mapis<Person<Pet>, ["pet"], ["meta", "type"], [], string>(
["pet"],
["meta", "type"],
{
dog: (person: Person<Dog>) => `Dog: ${person.pet.data.name}`,
cat: (person: Person<Cat>) => `Cat: ${person.pet.data.name}`,
}
);
function info(person: Person<Pet>): string {
return func(person);
}
console.log(
info({
pet: {
meta: { type: "dog" },
data: { name: "Rex" },
},
})
); // Dog: Rex
The type parameters that the function receives are the following:
- The type we are dealing with.
- The path to the key that we want to narrow down.
- The path to the discriminator key used to extract the subset.
- The extra parameters of the returned function.
- The return type of the returned function.
The function parameters that the functions receives are the following:
- The path to the key that we want to narrow down.
- The path to the discriminator key used to extract the subset.
- The mapper object with the keys and the corresponding functions.
Narrow utility type
If the Person
type was not generic we would need to use the Narrow
utility
type as you can see here:
import { mapis, Narrow } from "mapis";
interface Person {
pet: Pet;
}
type Pet = Dog | Cat;
interface Dog {
meta: { type: "dog" };
data: { name: string };
}
interface Cat {
meta: { type: "cat" };
data: { name: string };
}
type PersonWithDog = Narrow<Person, ["pet"], ["meta", "type"], "dog">;
type PersonWithCat = Narrow<Person, ["pet"], ["meta", "type"], "cat">;
const func = mapis<Person, ["pet"], ["meta", "type"], [], string>(
["pet"],
["meta", "type"],
{
dog: (person: PersonWithDog) => `Dog: ${person.pet.data.name}`,
cat: (person: PersonWithCat) => `Cat: ${person.pet.data.name}`,
}
);
function info(person: Person): string {
return func(person);
}
console.log(
info({
pet: {
meta: { type: "dog" },
data: { name: "Rex" },
},
})
); // Dog: Rex