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

Bad decode result when using union and undefined #677

Open
noshiro-pf opened this issue Nov 29, 2022 · 0 comments
Open

Bad decode result when using union and undefined #677

noshiro-pf opened this issue Nov 29, 2022 · 0 comments

Comments

@noshiro-pf
Copy link

noshiro-pf commented Nov 29, 2022

🐛 Bug report

Current Behavior & Expected behavior & Reproducible example

import * as t from 'io-ts';

const A = t.type({
  A: t.union([t.number, t.undefined, t.null]),
});

const B = t.type({
  B: t.union([t.number, t.undefined, t.null]),
});

const C = t.partial({
  C: t.union([t.number, t.null]),
});

const UnionAB = t.union([A, B]);
const UnionBA = t.union([B, A]);
const UnionAC = t.union([A, C]);
const UnionCA = t.union([C, A]);

const target = { A: 1 };

{
  const res = UnionAB.decode(target);
  if (isRight(res)) {
    console.log(res.right); // { A: 1 }  <- ok
    console.log(A.is(res.right)); // true  <- ok
    console.log(B.is(res.right)); // false  <- ok
  }
}

{
  const res = UnionBA.decode(target);
  if (isRight(res)) {
    console.log(res.right); // { A: 1, B: undefined }  <- NG (expected to be { A: 1 })
    console.log(A.is(res.right)); // true  <- ok
    console.log(B.is(res.right)); // true  <- NG (expected to be false)
  }
}

{
  const res = UnionCA.decode(target);
  if (isRight(res)) {
    console.log(res.right); // { A: 1 }  <- NG (expected to be {})
    console.log(A.is(res.right)); // true  <- ok
    console.log(C.is(res.right)); // true  <- ok
  }
}

{
  const res = UnionAC.decode(target);
  if (isRight(res)) {
    console.log(res.right); // { A: 1 }
    console.log(A.is(res.right)); // true  <- ok
    console.log(C.is(res.right)); // true  <- ok
  }
}

Suggested solution(s)

I think io-ts should distinguish between t.partial({ a: t.number }) and t.type({ a: t.union([t.number, t.undefined]) }) by using Object.hasOwnProperty in addition to checking if the key's value is undefined.

Additional context

Your environment

Which versions of io-ts are affected by this issue? Did this work in previous versions of io-ts?

Software Version(s)
io-ts 2.2.16
fp-ts 2.11.8
TypeScript 4.5.5
@noshiro-pf noshiro-pf changed the title union of union with Undefined Bad decode result when using union and undefined Nov 29, 2022
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

1 participant