Open joprice opened 3 months ago
Something I am not sure is when should we generate a lambda versus an "invokable" type.
For example,
export type ValueOrFunction1<T> = (req?: string) => T
generates
[<AllowNullLiteral>]
[<Interface>]
type ValueOrFunction1<'T> =
[<Emit("$0($1...)")>]
abstract member Invoke: ?req: string -> 'T
which has the benefit of support optional arguments which is not possible lambda as we would have something like string option -> 'T
In Glutinum.ExpressServeStaticCore
what I did at the time to have the best of both world was generate some helpers:
Perhaps, we should generate something like that:
open Fable.Core
open System
[<AllowNullLiteral>]
[<Interface>]
type ValueOrFunction<'T> =
[<Emit("$0($1...)")>]
abstract member Invoke: req: string * ?nextHandler : obj -> 'T
[<Emit("$0")>]
static member inline Create (f : Func<string option, string, 'T>) : ValueOrFunction<'T> = nativeOnly
// Here we can reate an instance to pass to the library
ValueOrFunction.Create(fun s a -> ()) |> ignore
// Imagine we get an instance of the function from the library
let func = ValueOrFunction.Create(fun s a -> ())
func.Invoke("request")
func.Invoke("request", null)
import { defaultOf } from "fable-library-js/Util.js";
import { some } from "fable-library-js/Option.js";
((s, a) => {
});
export const func = ((s, a) => {
});
func("request");
func("request", some(defaultOf()));
It allows us to create instance of the type in an "okay" way and also supports invoking the function when we get an instance of it from somewhere.
When a type parameter appears in a union, the type is generated as a type name, not a type variable, resulting in the error
The type 'T' is not defined
. Functions are also not yet handled in unions.translates into
Current:
Expected:
Example of npm package using this features:
https://github.com/LionC/express-basic-auth/blob/dd17b4de9fee9558269cdc583310bde5331456e7/express-basic-auth.d.ts#L58