I’m getting a strange runtime comparison issue. I defined a type like:
type method =
GET
| HEAD
| POST
| PUT
| DELETE
| PATCH
| CONNECT
| OPTIONS
| TRACE
For my own sanity in log messages, I have a way to convert those back:
let methodToString = method =>
switch method {
| GET => "get"
| HEAD => "head"
| POST => "post"
| PUT => "put"
| DELETE => "delete"
| PATCH => "patch"
| CONNECT => "connect"
| OPTIONS => "options"
| TRACE => "trace"
}
I then have some JSON I convert that may have that:
type jwtTokenPayload = {
at: option<string>,
ts: option<int>,
m: option<method>,
p: option<string>,
h: option<Js.Array.t<string>>,
hh: option<string>
}
@scope("JSON") @val
external jwkStringToJWK: string => jwk = "parse"
… and it’s pretty amazing. Coming from Elm where I have to write decoders, this is all like “boom, here’s your object, bruh”. Sick. HOWEVER… when I later go to compare, runtime oddness:
let methodMatches = (method, token) =>
switch token.payload {
| None => NoPayloadSoNoMethod
| Some(payload) => switch payload.m {
| None => NoMethodOnPayload
| Some(m) => {
Js.log2("ok, m is:", m)
Js.log2("but method is:", method)
Js.log2("ok, m is:", methodToString(m))
Js.log2("but method is:", methodToString(method))
if Js.String.toLowerCase(methodToString(m)) === Js.String.toLowerCase(methodToString(method)) {
MethodMatches
} else {
MethodDoesNotMatch(`method: ${methodToString(method)}, token.payload.m: ${methodToString(m)}`)
}
}
Ok, those 4 log messages? Look at these bonkers outputs:
Js.log2("ok, m is:", m) // GET
Js.log2("but method is:", method) // 0
Js.log2("ok, m is:", methodToString(m)) // undefined
Js.log2("but method is:", methodToString(method)) // get
So m
from JSON printing out as GET, while helpful, doesn’t follow the 8.2 docs (I’m using 9) stating it’ll generate JS to _0, _1, etc. But whatever, no big deal.
But method as 0 AND m is a problem. ReScript types both to method
, yet at runtime, they’re different. So when I run ===
it fails… because GET doesn’t === 0… but… dude, how in the the, wat does this even mean?
Ok last one up is methodToString
: his pattern match covers all angles… yet… he doesn’t because somehow it magically returns undefined
? How is this even possible?