assert properties of a object are non-null using a function's arguments

Solution 1:

I would approach this by making the opts.if argument be a function as opposed to a static boolean value.

This way, it's very simple to make the predicate match the type of the data that is passed as first argument.

const doSomethingWith = <T>(data: T) => data

const fn = <T>(data: T, opts?: { if: (t: T) => boolean }): void => {
  if (opts?.if(data) === false) return;

  doSomethingWith(data)
}

type Data = { abc: string }

const data: Partial<Data> = {}
const data2: Data = { abc: '123' }
const data3: Partial<Data> = {}


fn(data, { if: d => d.abc != null  }) // OK, valid predicate
fn(data2) // OK, no predicate
fn(data3, { if: d => d.foobar != null  }) // NOT OK, predicte doesn't match data

Playground