Skip to content

Commit a7e58cc

Browse files
authored
Add docs for ExternalDartReference (#5668)
This type was added as part of dart-lang/sdk#55187 to dart:js_interop for a faster alternative to JSBoxedDartObject, so we should add some documentation on it.
1 parent cc7d172 commit a7e58cc

File tree

1 file changed

+35
-8
lines changed

1 file changed

+35
-8
lines changed

src/content/interop/js-interop/js-types.md

+35-8
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,10 @@ JS types form a natural type hierarchy:
3535
- JS typed arrays like `JSUint8Array`
3636
- `JSBoxedDartObject`, which allows users to box and pass Dart values
3737
opaquely within the same Dart runtime
38+
- From Dart 3.4 onwards, the type `ExternalDartReference` in
39+
`dart:js_interop` also allows users to pass Dart values opaquely, but is
40+
*not* a JS type. Learn more about the tradeoffs between each option
41+
[here](#jsboxeddartobject-vs-externaldartreference).
3842

3943
You can find the definition of each type in the [`dart:js_interop` API docs].
4044

@@ -72,14 +76,15 @@ Generally, the conversion table looks like the following:
7276

7377
<div class="table-wrapper" markdown="1">
7478

75-
| JS type | Dart type |
76-
|-------------------------------------|------------------------------------------|
79+
| `dart:js_interop` type | Dart type |
80+
| ----------------------------------- | ---------------------------------------- |
7781
| `JSNumber`, `JSBoolean`, `JSString` | `num`, `int`, `double`, `bool`, `String` |
7882
| `JSExportedDartFunction` | `Function` |
7983
| `JSArray<T extends JSAny?>` | `List<T extends JSAny?>` |
8084
| `JSPromise<T extends JSAny?>` | `Future<T extends JSAny?>` |
8185
| Typed arrays like `JSUint8Array` | Typed lists from `dart:typed_data` |
8286
| `JSBoxedDartObject` | Opaque Dart value |
87+
| `ExternalDartReference` | Opaque Dart value |
8388

8489
{:.table .table-striped}
8590
</div>
@@ -103,8 +108,8 @@ specific conversion function for more details.
103108
In order to ensure type safety and consistency, the compiler places requirements
104109
on what types can flow into and out of JS. Passing arbitrary Dart values into JS
105110
is not allowed. Instead, the compiler requires users to use a compatible interop
106-
type or a primitive, which would then be implicitly converted by the compiler.
107-
For example, these would be allowed:
111+
type, `ExternalDartReference`, or a primitive, which would then be implicitly
112+
converted by the compiler. For example, these would be allowed:
108113

109114
```dart tag=good
110115
@JS()
@@ -123,6 +128,11 @@ extension type InteropType(JSObject _) implements JSObject {}
123128
external InteropType get interopType;
124129
```
125130

131+
```dart tag=good
132+
@JS()
133+
external void externalDartReference(ExternalDartReference _);
134+
```
135+
126136
Whereas these would return an error:
127137

128138
```dart tag=bad
@@ -240,9 +250,22 @@ to interop members or distinguish between JS `null` and `undefined` values,
240250
but this will likely change in the future. See [#54025] for more details.
241251
:::
242252

243-
{% comment %}
244-
TODO: add links (with stable) when ready:
245-
{% endcomment %}
253+
## `JSBoxedDartObject` vs `ExternalDartReference`
254+
255+
From Dart 3.4 onwards, both [`JSBoxedDartObject`] and [`ExternalDartReference`]
256+
can be used to pass opaque references to Dart `Object`s through JavaScript.
257+
However, `JSBoxedDartObject` wraps the opaque reference in a JavaScript object,
258+
while `ExternalDartReference` is the reference itself and therefore is not a JS
259+
type.
260+
261+
Use `JSBoxedDartObject` if you need a JS type or if you need extra checks to
262+
make sure Dart values don't get passed to another Dart runtime. For example, if
263+
the Dart object needs to be placed in a `JSArray` or passed to an API that
264+
accepts a `JSAny`, use `JSBoxedDartObject`. Use `ExternalDartReference`
265+
otherwise as it will be faster.
266+
267+
See [`toExternalReference`] and [`toDartObject`] to convert to and from an
268+
`ExternalDartReference`.
246269

247270
[`dart:js_interop`]: {{site.dart-api}}/{{site.sdkInfo.channel}}/dart-js_interop/dart-js_interop-library.html
248271
[`external`]: /language/functions#external
@@ -252,4 +275,8 @@ TODO: add links (with stable) when ready:
252275
[`instanceOfString`]: {{site.dart-api}}/{{site.sdkInfo.channel}}/dart-js_interop/JSAnyUtilityExtension/instanceOfString.html
253276
[`isA`]: {{site.dart-api}}/{{site.sdkInfo.channel}}/dart-js_interop/JSAnyUtilityExtension/isA.html
254277
[#4841]: https://github.com/dart-lang/linter/issues/4841
255-
[#54025]: https://github.com/dart-lang/sdk/issues/54025
278+
[#54025]: https://github.com/dart-lang/sdk/issues/54025
279+
[`JSBoxedDartObject`]: {{site.dart-api}}/{{site.sdkInfo.channel}}/dart-js_interop/JSBoxedDartObject-extension-type.html
280+
[`ExternalDartReference`]: {{site.dart-api}}/{{site.sdkInfo.channel}}/dart-js_interop/ExternalDartReference-extension-type.html
281+
[`toExternalReference`]: {{site.dart-api}}/{{site.sdkInfo.channel}}/dart-js_interop/ObjectToExternalDartReference/toExternalReference.html
282+
[`toDartObject`]: {{site.dart-api}}/{{site.sdkInfo.channel}}/dart-js_interop/ExternalDartReferenceToObject/toDartObject.html

0 commit comments

Comments
 (0)