Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Something like valueOr but for null? #128

Open
mnn opened this issue Jul 1, 2021 · 3 comments
Open

Something like valueOr but for null? #128

mnn opened this issue Jul 1, 2021 · 3 comments

Comments

@mnn
Copy link

mnn commented Jul 1, 2021

valueOr works well for | undefined fields, but not for | null fields. I didn't see any function to support this, but maybe I overlooked something?

import * as O from 'optics-ts';

interface ZUndef {
  a?: AUndef;
}

interface AUndef {
  b?: BUndef;
}

interface BUndef {
  x: number;
}

const testUndef = () => {
  const defaultA: AUndef = {};
  const defaultB: BUndef = {x: 7};

  const xO = O.optic<ZUndef>().prop('a').valueOr(defaultA).prop('b').valueOr(defaultB).prop('x');

  const data: ZUndef = {};

  const res = O.set(xO)(11)(data);

  console.log('undef', res); // ok: undef { a: { b: { x: 11 } } }
};

testUndef();

// ---

interface ZNull {
  a: ANull | null;
}

interface ANull {
  b: BNull | null;
}

interface BNull {
  x: number;
}

const testNull = () => {

  const defaultA: ANull = {b: null};
  const defaultB: BNull = {x: 7};

  const xO = O.optic<ZNull>().prop('a').valueOr(defaultA).prop('b').valueOr(defaultB).prop('x'); // TS2345: Argument of type 'string' is not assignable to parameter of type 'never'.

  const data: ZNull = {a: null};

  const res = O.set(xO)(11)(data); // TypeError: Cannot read property 'b' of null

  console.log('null', res);
};

testNull();
@akheron
Copy link
Owner

akheron commented Oct 22, 2021

Yeah, unfortunately there's no support for null yet. At some point I was pondering whether null should be treated the same way as undefined, so that e.g. optional() and valueOr() would consider null a missing value.

@jsit
Copy link

jsit commented Apr 4, 2024

What's a good way of working around this? Something with .lens()?

@jsit
Copy link

jsit commented May 9, 2024

For instance, @mnn, I think you could do this:

  const xO = O.optic<ZNull>()
    .prop('a')
    .lens(
      a => a ?? defaultA,
      (a, update) => update,
    )
    .prop('b')
    .lens(
      b => b ?? defaultB,
      (b, update) => update,
    )
    .prop('x');

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants