I’m working on interfacing with some heavily inheritance based JS, and was wondering if I could somehow model the following scenario (in TS for typing):
type Thing;
interface HasThing {
thing: Thing;
}
interface Item extends HasThing {
thing: Thing;
foo: Foo
}
const doThing: (thing: HasThing) => do(thing.thing);
I feel like functors are maybe the right path? But then how:
- Can I “appened” the
thing
field to a ReScript record type? Is it even possible?
- Can I “use” the functor type in my function signature?
- Can I combine many functors together (as this isn’t the only field like this)?
Ideally I don’t have to list every permutation, as it has just enough permutations to be both tedious and doItemThing
seems frustrating to write.
Otherwise, this language has been a total dream
1 Like
It would look something like:
type thing
module type HasThing = {
let thing: thing
}
module type Item = {
include HasThing
let foo: foo
}
// Functor approach
module DoThing = (Thing: HasThing) => {
do(Thing.thing)
}
// First-class module approach
let doThing = (thing: (module HasThing)) => {
let (module Thing) = thing
do(Thing.thing)
}
You can go with either approach.
- The
thing
field is inside a module type, so it can’t be appended to a record type
- Yes, see the first-class module approach above (you may need to tweak the syntax a bit, I’m not sure I got it totally right in ReScript syntax)
- If by ‘combine’ you mean the
Thing
functor argument can ‘inherit’ or ‘extend’ many interfaces, then yes you can, e.g.
module DoThing = (Thing: {
include HasThing
include HasOtherThing
include HasSomethingElse
}) => {
do(Thing.thing)
}
Same for the first-class module approach.
3 Likes