Ts-toolbelt: How can I filter an object by another鈥檚 values?

Created on 18 Mar 2020  路  3Comments  路  Source: millsp/ts-toolbelt

馃 Question

Describe your question

Say we have an interface with some fields:

interface Data {
  x: string;
  y: string;
}

and a function that takes an object to select fields from that interface:

function select(opts: { x: boolean, y: boolean }) {
  const data: Data = getData() // from somewhere
  const o = {};
  for (const key in data) {
    if (opts[key] === true) o[key] = data[key];
  }
  return o;
}

How could we type the return such that it excludes fields in Data that are not true in the options object provided to select?

Thanks!

Search tags, topics

typescript #object #filter #exclude

question wiki

All 3 comments

It isn't possible so easily. Though it might be possible through writing you own custom type. First of all, start writing the type that will perform this:

interface Data {
    x: string;
    y: string;
}

type SelectIfTrue<O extends object, O1 extends object> =
    O.Pick<O, O.SelectKeys<O1, true>>

type t0 = SelectIfTrue<Data, {x: true, y: false}> // works

Then, you integrate the type to your function by casting its result:

// you will have to use `as const`. so we use a generic parameter
function select<O extends object>(opts: O) {
    const data: Data = {} as Data // from somewhere
    const o = {}

    for (const key in data)
        if (opts[key] === true) o[key] = data[key]

    return o as SelectIfTrue<Data, O> // casting the result
}

const t1 = select({x: true, y: false})          // not working
const t2 = select({x: true, y: false} as const) // works

I find this cumbersome. It is good to try to summarize TypeScript types. Even though this library can allow you to do such computations, you should not try to compute absolutely everything. Instead, your select should spit a simpler type out:

type t2 = O.Optional<Data>

@pirix-gh Thank you! Perhaps I should be less precise, it just seemed like it would be nice given the strict coupling between input and output. Thanks also for these great tools! 馃槂

Oh, although I notice that at least with the strict compiler option the as const assertion isn鈥檛 necessary, which was the main thing I disliked as it鈥檚 user-facing. Nice! Thanks again for your help.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

xaviergonz picture xaviergonz  路  3Comments

regevbr picture regevbr  路  7Comments

millsp picture millsp  路  6Comments

ctrlplusb picture ctrlplusb  路  5Comments

mesqueeb picture mesqueeb  路  5Comments