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
Jsonify
removes all optional properties
#309
Comments
// @darcyparker |
This does seem to be the case. |
@bbrk24 - Thanks for reporting these edge cases. I am looking at it now. |
The underlying issue seems to be the use of type T = Extract<string, NotJsonable>; // type T = never
// never | x == x, so...
type U = Extract<string | undefined, NotJsonable>; // type U = undefined
type V = Exclude<undefined, NotJsonable>; // type V = never
type W = Exclude<string | undefined, NotJsonable>; // type W = string So I think the correct solution has to test both. |
I understand/agree with the expected types of your example You're right that the My understanding of the problem is that optional properties must be handled. This is different than a required property that is set to
Am I understanding things correctly? Or I am missing something about the issue or your last comment? |
Ah, you have a point there. I hadn't considered the case of an explicit type union with If it were possible to conditionally add the |
Yeah... its not an easy problem. In my draft of #310, I made some progress... My comment that defines But then I discovered a problem with: declare const objectWithUndefinedValue: {x: undefined};
expectNotAssignable<JsonValue>(objectWithUndefinedValue); //I expected this to pass The above test illustrates a problem with But you're right that it may not be possible. |
I think I have an idea. I'm not 100% sure if this exact implementation will work but my idea is something like // replace `undefined` in `T` with the corresponding member from `U`
type OverwriteUndefineds<T, U extends {[_ in keyof T]?: any}> = {
[K in keyof T]: T[K] extends undefined ? U[K] : T[K]
};
type Jsonify<T> = // ...
// same as currently up until the object handler, which becomes:
OverwriteUndefineds<
{[P in keyof T]: Jsonify<T[P]> extends never ? undefined : Jsonify<T[P]>},
{[P in keyof Required<T>]?: Jsonify<Required<T>[P]>}
>
// ... I will have to think about it a bit more to get the exact details working, but my cursory testing shows that |
And I just realized I've been overthinking this entire thing. The solution is way simpler than that: just |
@darcyparker I'm pretty sure this is a TypeScript thing. I would imagine that if you use TypeScript 4.4 and set |
I assume this isn't the intended behavior.
So far I'm working around it by using
Partial<Jsonify<Required<T>>>
rather thanJsonify<T>
, but I can imagine situations where that's still not desirable (i.e. only some keys are optional, soPartial
doesn't work).I haven't looked too far into this, but if I had to guess what's happening:
undefined
tox
's type, givingstring | undefined
.undefined
isn't valid JSON, it fails theNotJsonable
check, soJsonify
returns{ x?: never }
undefined
, butundefined | never
collapses to justundefined
.It's also worth noting that while
undefined
is not normally valid in JSON,undefined
in an array becomesnull
.The text was updated successfully, but these errors were encountered: