Fable: how to override a JS class method imported from a JavaScript external library? (typed)

299 views Asked by At

What is the expected way to extend a class imported from a Javacript library while at the same being capable to call parent's members?

I tried several alternatives, using abstract classes apparently worked without errors but the child cannot call parent's abstract method, with interfaces there were no errors either but I cannot call to parent's class as there is no reference.

The best method I found is the following one overriding the mezhods, and althought the yielt code works, the compiler still emits an error:

error FSHARP: No abstract or interface member was found that corresponds to this override (code 855)

My current code:

    [<Import("DataManager", from="library/data")>]
    type DataManager<'Model> (conf:obj) =
        class
            member this.insert(_:'Model):Promise<obj> = jsNative
            member this.update (_:'Model):Promise<obj> = jsNative
        end

    type MyAdaptor<'Model> (conf, inst)=
        inherit DataManager<'Model> (conf)
        let DB:obj = inst
        do
            printf "I've been created"

        override this.insert(o:'Model):Promise<obj> =
            printf "insert method comes with object:"
            console.log o
            base.insert o
            //Constructors.Promise.Create o

        override this.update(o:'Model): Promise<obj> =
            printf "Update method comes with object:"
            console.log o
            base.update o
            //Constructors.Promise.Create o

Previously I also tried to use just members and still call base's method but althought it compiled without issue, when calling instance's methods only parent's code was executed. I am afraid it might be a bug.

I also had several tries callint the inheritance manually in a self-made constructor but it usually fails to compile because the imported JS was either not recognize as a valid constructor or then I couldn't include the method definitions (I care about type safety).

1

There are 1 answers

0
Víctor R. Escobar On

It turns out that in F# people cannot override a method which has not been declared previously as abstract.

For that the solution was to declare the methods as abstract and provide a default implementation before override.

   [<Import("DataManager", from="library/data")>]
   type DataManager<'Model> (conf:obj) =
        class
            abstract member insert: 'Model -> Promise<obj>
            default this.insert(_:'Model):Promise<obj> = jsNative

            abstract member update:'Model -> Promise<obj>
            default this.update (_:'Model):Promise<obj> = jsNative
        end

After that it is possible to override the child class without issues.