Skip to content

Make JSExportedDartFunction generic and add a toJSGeneric function #54557

@srujzs

Description

@srujzs

It is useful to know the type of the Dart function that is now being wrapped by a JS function. Imagine an interface like:

@JS()
external set callback(JSFunction f);

where callback is called later at some point. The external member has no way of validating that f is a function that will work with the inputs that are passed and produces an output that is expected. If f wraps a function with the wrong type, this results in a runtime error later. In order to have some better static checking, we essentially need to duplicate the member:

@JS('callback')
external set _callback(JSFunction f);
set callback(void Function(int) f) => _callback = f.toJS;

Instead, we can improve the static checking here by making JSExportedDartFunction generic with a bound of Function and exposing a member that produces the generic type e.g.

JSExportedDartFunction<T> toJSGeneric<T extends Function>(T t) => t.toJS as JSExportedDartFunction<T>;

which would then result in code like:

@JS()
external set callback(JSExportedDartFunction<void Function(int)> f);

Granted, unlike with the example with two setters, this doesn't stop users from casting one JSExportedDartFunction to another JSExportedDartFunction and basically lie about the generics, but this makes it statically obvious what JS is expecting.

Metadata

Metadata

Assignees

No one assigned

    Labels

    area-web-jsIssues related to JavaScript support for Dart Web, including DDC, dart2js, and JS interop.web-js-interopIssues that impact all js interop

    Type

    No type

    Projects

    Status

    Backlog

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions