Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Variables with generic type parameter fail to compile #401

Open
Booksbaum opened this issue Apr 3, 2021 · 1 comment
Open

Variables with generic type parameter fail to compile #401

Booksbaum opened this issue Apr 3, 2021 · 1 comment

Comments

@Booksbaum
Copy link
Contributor

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)

@Booksbaum
Copy link
Contributor Author

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).

Booksbaum added a commit that referenced this issue Apr 25, 2021
…er (#412)

* Fix brackets for variables with generic types

Variables are now transformed into Properties:
Variables were already emitted as F# Properties, but their handling was
different
from real Properties. Now Variables are converted into Properties in
`transform.fs`
and can use the same print code as real Properties.
Exception: Top level variables. These are printed as `let` binding,
not abstract members in an interface.

* Add Generic Type Constraints for Variables and Properties

* Add tests for interface

(Properties instead of variables -- but same issues for function
properties)

* Add tests for class

* Add more tests

Add (more) tests for multiple parameter:
Strange behaviour in F#:
`abstract v: string -> string -> string` is ok,
`abstract v: string -> string -> string` isn't, but required brackets
Further with generyc type parameter:
`abstract v: 'T -> 'T -> 'T` is ok, but (unlike with just `string`)
`abstract v: ('T -> 'T -> 'T)` is not (type parameter 'T is not defined)

Add tests for optional property:
Again strange behaviour in F#:
`abstract o: 'T option` isn't allowed, but
`abstract o: 'T option with get,set` is.

Most of these cases most likely don't occur in real code.
In the source for this issue and its tests it's not a general `'T`,
but a limitation (subset) of a string Enum

* Revert: Don't handle Variable in `printType`

There might be cases a Variable wasn't transformed into a property.
These would now fail. To prevent this Variables are now again handled in
`printType` as a fallback. Additional a log message is printed to
console.

* Add tests for static members
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant