How to conditionally populate the value of an object

I set this code in a playground

type out_value1 = {"model": string}
type out_value2 = {"model": string, "spec": string}

// if inputSave.system === "V1" it should use out_value1 and if inputSave.system === "V2" it should use out_value2
type inputSave = {
  "system": string,
  "value": out_value1
}
 
let save = inputSave => {
  Js.log(inputSave)
  // calls the http API
}

I need to use a different type for value depending on the value of the system field so I can save it to my database accordingly.

I am thinking of using Objects since are more flexible than Records but not sure how to achieve this. I’m open for suggestions. I was also trying to figure out how to use %identity for this case.

1 Like

If you’re using ReScript 11, I think you should use the new bindings for discriminated unions. As in:

@tag("system")
type inputSave =
  | @as("V1") V1({value: out_value1})
  | @as("V2") V2({value: out_value2})

let saveVal = V1({value: {"model": "foo"}})

/* Compiles to:
var saveVal = {
  system: "V1",
  value: {
    model: "foo"
  }
};
*/
5 Likes

I’m still v10. is v11 ready for production?
thanks for the playground example :+1:

Then again, do you need inputSave to be that shape exactly? E.g., do you need TypeScript/npm libraries interop? Because for your save function, you could go with normal ReScript variants.

type inputSave =
  | V1(out_value1)
  | V2(out_value2)

let save = inputSave =>
  switch inputSave {
  | V1(val) => saveV1(val)
  | V2(val) => saveV2(val)
  }
1 Like

I think so. It’s not officially out of the beta phase, but the alpha has been out long enough so we know it’s working pretty well.

3 Likes

yeah I do need to save it by saving it to a TS server implemented with convex.dev
so your new bindings example is ideal for my use case

trying to use v11 but can’t figure out how to curry
do you know how?

I tried to put @@uncurried at the top of the file but that doesn’t do anything

I think you can start by adding "uncurried": false to your bsconfig, and then gradually add @@uncurried to the files where you want to introduce the uncurried semantics.

3 Likes

ah got it, thanks

I am having this error: “This expression is expected to have an uncurried function”

let toPis: toPis = arr => arr->Array.map(n => n *. Math.Constants.pi)
let toPis: array<float> => array<float>

Seems to me like it is correct so no clue how to fix the error

using rescript-core 0.4

I’ll guess I’ll have to drop rescript-core

rescript-core is in preparation for 1.0 which will be optimized for rescript v11 usage ([WIP] Rescript v11 by zth · Pull Request #135 · rescript-association/rescript-core · GitHub).

2 Likes

thanks, I think I’ll have to temporarily drop it because v11 is more valuable than core at the present state

Core should work fine with v11, I use it myself. Can you try clearing node_modules, cleaning and rebuilding?

oh I just removed rescript-core and took me a while… I’ll try it in another project when I get to it

1 Like

I was late to this question, but if you want to stick to v10 for now, you can use Records with optional fields like so.

thank you, I already switched to V11… it is awesome with the new tag literals but I’m still a bit confused on curry