ts2fable icon indicating copy to clipboard operation
ts2fable copied to clipboard

Inheriting from Error/Exception not possible

Open Booksbaum opened this issue 5 years ago • 3 comments

Inheriting from Error/Exception isn't possible:

export class MyError extends Error { }

gets converted into (abbreviated)

type Error = System.Exception

type [<AllowNullLiteral>] MyError =
    inherit Error

Which results in the error

The type 'Error' is not an interface type

MyError is an interface, while Error/Exception isn't.

Possible fix: make it abstract:

type [<AllowNullLiteral; AbstractClass>] MyError =
    inherit Error

Same for other abbreviated types that aren't interfaces.
Making classes with such inheritance abstract would be an issue when no unit-ctor, or sealed type (Function -> System.Action). And abstract would need to bubble up with more inheritance like class MyOtherError extends MyError {}.

Booksbaum avatar Oct 24 '20 15:10 Booksbaum

Having the same problem, with axios types in my case.

Any suggestion on how to fix it? I'm currently having trouble pattern matching axios errors :(

alarbada avatar Mar 12 '21 02:03 alarbada

Hello @not-rusty,

if adding AbstractClass works for you, you can just fix the bindings manually.

At least, that's how I did it in my case.

MangelMaxime avatar Mar 12 '21 07:03 MangelMaxime

Actually, it seems like when adding AbstractClass to a type is different.

open System
open Fable.Core

type [<AllowNullLiteral; >] DatabaseError =
    // inherit System.Exception
    abstract code: string option

let x = unbox<DatabaseError> null

let code = x.code

generates

export const x = null;

export const code = x.code;

but

open System
open Fable.Core

type [<AllowNullLiteral; AbstractClass >] DatabaseError =
    // inherit System.Exception
    abstract code: string option


let x = unbox<DatabaseError> null

let code = x.code

generates

import { class_type } from "fable-library/Reflection.js";

export class DatabaseError {
    constructor() {
    }
}

export function DatabaseError$reflection() {
    return class_type("Test.DatabaseError", void 0, DatabaseError);
}

export const x = null;

export const code = x["Test.DatabaseError.get_code"]();

which is not what we want in the case of a bindings.

MangelMaxime avatar Jul 21 '21 12:07 MangelMaxime