Properties with optional object with its own optional properties returns empty object
Hi!
Given this snippet of code:
const optionalTest = record({
id: optional(string)
});
const objDecoder = record({
id: number,
name: string,
optionalId: optional(optionalTest),
});
type Obj = decodeType<typeof objDecoder>;
optionalTest returns an empty object when accessing it through objDecoder.
I have used your example code and rewritten it to reproduce the potential bug: https://codesandbox.io/s/typescript-json-decoder-playground-forked-pcx8f7?file=/src/App.tsx
As you can se, typescript complains that id does not exist on an empty object.
Edit: stopped working after upgrading from 1.0.7 to 1.0.10
Is this intentional or a bug? :)
Hi, thanks for creating the issue!
This is definitely a bug. Did I understand correctly that this worked properly in 1.0.7, but broke on 1.0.10? 1.0.10 was IIRC a workaround for a bug in TypeScript's type inference that caused something similar to happen, so I wouldn't be surprised if this workaround is the thing breaking your example.
I'll look into if there's anything I can do, but this might be a situation where it's not possible solve both issues at the same time, without getting a fix upstream from TypeScript.
Okay so I've looked into it some more, and this is still the same bug in the TypeScript compiler that version 1.0.10 was meant to work around. I can't seem to find a workaround that solves all cases, so until TypeScript gets a fix for this I'm afraid you have to work around it in the application layer.
Can you try this: add an optional(number) field to the optionalTest object, so that it becomes the following:
const optionalTest = record({
id: optional(string),
bugfix: optional(number)
});
This seems to avoid the pathological case in TypeScript's type inference algorithm. Of course it's completely stupid and means you have to have a redunant optional field in your data, but I'm not sure what else to do. If you don't care about the ? feature, you might consider staying on 1.0.7 for now.
We can keep staying on v1.0.7, that won't be that big of a problem. I'll check in with the team to see if the workaround with number is feasible or if we'll just keep using 1.0.7.
Thanks for looking into it! Hopefully it gets fixed upstream some day. You can close the issue if you want to, or let it stay open for others / until they fix it :)
Thanks for the understanding!
Having literally any other field on the object fixes it, the only case it breaks is if you have an optional record with only an optional(string). Don't know why string is so special.
I'm sure there exists other workarounds, so if you find any please share them!