gcanti / monocle-ts

Functional optics: a (partial) porting of Scala monocle
https://gcanti.github.io/monocle-ts/
MIT License
1.05k stars 52 forks source link

How-to: select optional props from record. #178

Open SimonAM opened 2 years ago

SimonAM commented 2 years ago

📖 Documentation

I have a string array K[ ] of possible keys for a record. (could be inside an option, but this is not necessary). I want to select matching props from Record<K, V> and ignore any Ks not matching. If no Ks matches, stick it in a none, else a some.

Is this a problem for monocle-ts to solve? If so, how?

SimonAM commented 2 years ago

Example below

interface Person {
  name: string;
}
interface PersonState {
  [key: string]: Person;
}
const person1: Person = {
  name: "Geralt of Rivia"
};
const person2: Person = {
  name: "Yen of Vengeberg"
};
const personState: PersonState = {
  person1,
  person2
};

const personLens: Lens<PersonState, Person> = Lens.fromProps<PersonState>()([
  "person1",
  "person2"
]);

const objectOptional = new Optional<PersonState, PersonState>(
  (s) => (s === {} |? none : some(s)), // getOption
  (a) => (s) => ({ ...s, ...a }) // set
);

console.log(
  "multiple props with lens",
  props<PersonState, string>(
    "person3",
    "person4"
  )(objectOptional).getOption(personState)
);  // some({person3: undefined, person4: undefined})

optional.props can read multiple keys of an object. But if the keys are missing on the object we end up with an unhelpful key: undefined. I would want the props to return only the keys that are matching, and if no keys are matching, return a none.