lossless-json icon indicating copy to clipboard operation
lossless-json copied to clipboard

JSON and LosslessNumber types

Open josdejong opened this issue 3 years ago • 0 comments

From #244:

I was disappointed that LosslessNumber instance of Number is false, also I get weird type errors from lossless-json, I had to add an any (d is a string):

      const dataAsLosslessJson = losslessJsonParse(d);
      jsonDataString = "json_data = " + objToPython(dataAsLosslessJson as any) + "\n";

if I remove the as any, I get a type error from objToPython saying Argument of type 'unknown' is not assignable to parameter of type 'string | number | boolean | object | null'. ts(2345). Why does it think dataAsLosslessJson is unknown?

I'm a bit struggling with defining types for the library. For example the native JSON.parse is in my IDE giving the following TypeScript types:

interface JSON {
  parse(text: string, reviver?: (this: any, key: string, value: any) => any): any;
}

Which is quite generic.

We can define JSON like:

https://github.com/josdejong/lossless-json/blob/94d906cf255123e82a57b44bcc6ed0c6923599ec/src/types.ts#L1-L7

But as soon as we have a reviver and/or numberParser, the output can be sort of anything. I tried to represent this as:

https://github.com/josdejong/lossless-json/blob/94d906cf255123e82a57b44bcc6ed0c6923599ec/src/types.ts#L9-L15

So, there are two different levels of JSON, but what types can really come out of the function depend on the reviver and numberParser. Maybe with generics it is possible to define this strictly instead of relying on unknown (which covers LosselessNumber and anything).

Now, as for your specific questions and ideas:

  1. The output of LosslessJSON.parse() is a JavaScriptValue. Your function objToPython(obj: string | number | boolean | object | null, indent = 0) does not accept the more broad definition of JavaScriptValue so it makes sense that TypeScript complains about that. I guess the logic solution is to make the first argument of objToPython compatible with JavaScriptValue. Or we have to be able to
  2. It is an interesting idea to make LosslessNumber extend Number. I have to think that through a bit. It would make the wrapper class less lightweight: we would have to add all methods that Number has. But it can make usage more natural, and maybe we could make JSON.parse return JSONValue instead of JavaScriptValue somehow 🤔

josdejong avatar Nov 22 '22 17:11 josdejong