I'm confused with unknown for bindings

Greetings.

I read the Unknown for type safety section, but then I got stuck. How to actually make getPropertySafe work?

I was writing bindings for an external library. There is a sub/push mechanism. I think you guys can got an idea from the following code:

websocket.onPush = (cmd, res)=>{
        if(ftCmdID.QotUpdateOrderBook.cmd == cmd){
            let { retType, s2c } = res
            if(retType == RetType.RetType_Succeed){
                console.log("OrderBookTest", s2c);
            } else {
                console.log("OrderBookTest: error")
            }
        }
    };

I wrote the binding for onPush like this: @send external onpush: (ftwebsocket, (~cmd: int, ~res: unknown) => unit) => unit = "onPush". The res type shape depends on the matched cmd.

What’s the proper way to do these kind of bindings? Thanks!

If there is a predictable amount of combinations, I would write multiple bindings for the same function.

@send external onpushString: (ftwebsocket, (~cmd: string, ~res: string) => unit) => unit = "onPush"

@send external onpushInt: (ftwebsocket, (~cmd: int, ~res: int) => unit) => unit = "onPush"

@send external onpushFloat: (ftwebsocket, (~cmd: float, ~res: float) => unit) => unit = "onPush"

Or you could use a generic type for the function which defines the cmd and res type

type onpush<'cmd, 'res> = (free socket, ~cmd: 'cmd, ...

@send external onpushFloat: onpush<float, float> = "onPush"

There are nearly hundred of cmds, I think multiple bindings are not suitable.

Also the onPush callback is likely to set for once, and respond for all potential cmd subs.

This might be a good use for an unboxed variant type.

Well, the current documentation around unknown is not very helpful, unknown is pretty much a dead end unless you actually parse it. It’s not a great fit for bindings to functions where you actually know the shape of the value.

The real question here is how would you handle these values in js? Would it follow some kind of rules or would you have to parse it every time?

Yes, different cmds’ response mapped to a protobuf definition. I think unbox might be the solution? Seems I need to parse it every time.

I just found to parse every cmd’s response is verbose and massive work. It also seems unnecessary since I have already defined every cmd’s response type(according to protobuf).

I’m looking for something like in typescript that can specify type for an unknown data: let res: SomeCmdPushData = unknown_res_data. Is that possible or other better solutions in rescript?

Ah, I made it with generic. I misused unknown, because the response data is actually NOT unknown.

2 Likes