Now about some observations of where ReScript might be improved for better DX
Properly bind with @taggedTemplate
Currently the @taggedTemplate works correctly only for functions with two arguments.
When applied to a function with three arguments where the first one is actually the function to call, the generated JS code is just incorrect.
It would be great if the following:
@send @taggedTemplate
external query: (sql, array<string>, array<part>) => Promise.t<array<'row>> = "%identity"
…would translate to:
whateverFunction.on.the.FirstPosition`actually the content of the ${template} string passed as is`
Partial records
In TypeScript I can:
type record = {
a: string,
b: number,
c: boolean,
}
type partialRecord = Partial<record>
This is super-helpful to express concept of an update “patch” applied to some entity (PUT/PATCH in REST terms) where I can update precisely only 3 out of 100 fields of the entity.
I would cry with happy tears if some day ReScript gets the same built-in:
// Fantasy
type record = {
a: string,
b: float,
c: bool,
}
type partialRecord = partial<record>
// Equivalent to
type partialRecord = {
a?: string,
b?: float,
c?: bool,
}
Probably it’s too desperate to dream of, but keyof, Pick and Omit from TypeScript can make ReScript to the next level as well:
// Fantasy
type record = {
id: Uuid.t,
a: string,
b: float,
c: bool,
}
type recordWithoutSomeFields = omit<record, [#id | #a]>
type recordWithSomeFields = pick<record, [#b | #c]>
type keys = keyof<record> // equivalent to type keys = [#id | #a | #b | #c]
Easier coercing without Obj.magic
When dealing with frontend, backend logic, database access at once it’s often required to switch back and forth between records, objects and JSON.t directly, without repeating/reconstructing 100 fields again and again. It would help a lot if I can do the following:
type record = {
a: string,
b: float,
c: bool,
}
let a = "some string"
let b = 1234.0
let c = true
let recordObject = record :> {..} // this can be a no-op, right?
let recordObject2 = record :> {"a": string, "b": float} // can be type-checked
let recordBack = {"a": a, "b": b, "c": c} :> record // compiles only if shape matches
let myJson = {a, b, c} :> JSON.t
let myJson2 = {"a": a} :> JSON.t
Whew, enough dreaming. I hope some day ReScript on backend might become as fluent as crafting ReScript React components one after another.