fable-compiler/ts2fable

Variables with generic type parameter fail to compile

Opened this issue · 1 comments

export declare namespace N {
    const f1: (value: string) => number;

    const f2: <T>(value: T) => number;
    const f3: <T>(value: string) => T;
    const f4: <T>(value: T) => T;
}

==>

module N =
    type [<AllowNullLiteral>] IExports =
        abstract f1: (string -> float)

        abstract f2: ('T -> float)
        abstract f3: (string -> 'T)
        abstract f4: ('T -> 'T)

Compile Error for f2, f3, f4:

error FS0039: The type parameter 'T is not defined.

Shouldn't be surrounded by brackets:

module N =
    type [<AllowNullLiteral>] IExports =
        abstract f1: (string -> float)

        abstract f2: 'T -> float
        abstract f3: string -> 'T
        abstract f4: 'T -> 'T

-> compiles

(no. 1 in #295)

Issue with Top-level function-variables: require named parameter when generic:

let [<Import(...)>] f4: ('T -> 'T) = jsNativ
let [<Import(...)>] f4': 'T -> 'T = jsNative

error for both:

error FS0030: Value restriction. The value 'f4' has been inferred to have generic type val f4 : ('_T -> '_T) Either make the arguments to 'f4' explicit o r, if you do not intend for it to be generic, add a type annotation.

Must be:

let [<Import(...)>] f4 (value: 'T): 'T = jsNative

Advantage: contains parameter name.

Further: top-level variables cannot be mutable (see #399). So for now even let and var can be converted into let-functions.



In other places (in F#: in interfaces): might be reasonable to convert const function-variables into functions:

type IExports =
  abstract f4: value: 'T -> 'T

Advantage: contains parameter name. Valid for const as it doesn't have to be settable (unlike let and var).