Wrapper type for Javascript value

Is there a type that functions like

type JavaScriptType = JSString String | JSNumber Float | JSUndefined | JSNull | JSBoolean Boolean | JSSymbol String | JSObject ??? | JSArray ???

but without putting a wrapper around each value?

I have really big data sets, JS arrays containing up to 1,000,000 values, typically string, number or boolean, but also objects, so ??? above should preferable handle the recursive case.

I would instead like the ELM-case statement use run-time typeof checks.

Is this already implemented, what is it called?

This does not fit the exact shape you asked for, but you accept a Json.Decode.Value from either flags or a port, and pass it arbitrary JS objects. Once you need them, you can decode them with Json.Decode.decodeValue. To make the thing you mentioned, you might do:

type JSType = JSString String | JSNumber Float | ... | JSArray (List JSType)

decodeJSType : Decoder JSType
decodeJSType =
        [ Decode.map JSString Decode.string
        , Decode.map JSFloat Decode.float
        , ...
        , Decode.map JSArray (Decode.list (Decode.lazy (\_ -> decodeJSType)))

I’m not sure how you would represent undefined but the rest seem feasible. It’ll be way faster to decode into a shape you care about instead of a generic JSType thing, though, if it’s possible for your use-case!

1 Like

It’s worth noting that Json.Decode.Value is your JavaScriptType type, just without the constructors exposed. Such a type is so broad you can’t really do much with it without constantly casing (“is this a string”, “is there a nested object under key ‘x’”, etc). The JSON decoder API is built to abstract away all that casing.

Note that the elm/json library is partly implemented in JavaScript. As such you may not find what you expect if you try to go source diving. This article on implementing your own json-decode library walk through the json decoding process in pure Elm, including building a type very similar to your JavaScriptType.

To your actual problem: if you plan to use your data in Elm you will first want to define an Elm type that describes the form you want to use it and then decode your amorphous JS data into it.

It’s a bit strange that your JS array contains such a broad variety of data types though? Decoding into your JavaScriptType isn’t really useful, it may as well stay as a Json.Decode.Value at that point. Is there some narrower Elm type you want to use?

If you plan to use your data in JS and only wanted Elm to do some type-checking for you, you may be better off using TypeScript and one of the TypeScript decoding libraries. This will work the same as the Elm solution.

The reason I do not want to decode it and keep the decoded result, is that the amount of data is huge. The JavaScript JIT compiler is optimized to handle switching on run-time types, so if I do this right, there will no performance penalty, only gains in smaller heap.

There are properly typed code below.

This topic was automatically closed 10 days after the last reply. New replies are no longer allowed.