@@ -35,6 +35,10 @@ JS types form a natural type hierarchy:
35
35
- JS typed arrays like ` JSUint8Array `
36
36
- ` JSBoxedDartObject ` , which allows users to box and pass Dart values
37
37
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 ) .
38
42
39
43
You can find the definition of each type in the [ ` dart:js_interop ` API docs] .
40
44
@@ -72,14 +76,15 @@ Generally, the conversion table looks like the following:
72
76
73
77
<div class =" table-wrapper " markdown =" 1 " >
74
78
75
- | JS type | Dart type |
76
- | ------------------------------------- | ------------------------------------------ |
79
+ | ` dart:js_interop ` type | Dart type |
80
+ | ----------------------------------- | ---------------------------------------- |
77
81
| ` JSNumber ` , ` JSBoolean ` , ` JSString ` | ` num ` , ` int ` , ` double ` , ` bool ` , ` String ` |
78
82
| ` JSExportedDartFunction ` | ` Function ` |
79
83
| ` JSArray<T extends JSAny?> ` | ` List<T extends JSAny?> ` |
80
84
| ` JSPromise<T extends JSAny?> ` | ` Future<T extends JSAny?> ` |
81
85
| Typed arrays like ` JSUint8Array ` | Typed lists from ` dart:typed_data ` |
82
86
| ` JSBoxedDartObject ` | Opaque Dart value |
87
+ | ` ExternalDartReference ` | Opaque Dart value |
83
88
84
89
{:.table .table-striped}
85
90
</div >
@@ -103,8 +108,8 @@ specific conversion function for more details.
103
108
In order to ensure type safety and consistency, the compiler places requirements
104
109
on what types can flow into and out of JS. Passing arbitrary Dart values into JS
105
110
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:
108
113
109
114
``` dart tag=good
110
115
@JS()
@@ -123,6 +128,11 @@ extension type InteropType(JSObject _) implements JSObject {}
123
128
external InteropType get interopType;
124
129
```
125
130
131
+ ``` dart tag=good
132
+ @JS()
133
+ external void externalDartReference(ExternalDartReference _);
134
+ ```
135
+
126
136
Whereas these would return an error:
127
137
128
138
``` dart tag=bad
@@ -240,9 +250,22 @@ to interop members or distinguish between JS `null` and `undefined` values,
240
250
but this will likely change in the future. See [ #54025 ] for more details.
241
251
:::
242
252
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 ` .
246
269
247
270
[ `dart:js_interop` ] : {{site.dart-api}}/{{site.sdkInfo.channel}}/dart-js_interop/dart-js_interop-library.html
248
271
[ `external` ] : /language/functions#external
@@ -252,4 +275,8 @@ TODO: add links (with stable) when ready:
252
275
[ `instanceOfString` ] : {{site.dart-api}}/{{site.sdkInfo.channel}}/dart-js_interop/JSAnyUtilityExtension/instanceOfString.html
253
276
[ `isA` ] : {{site.dart-api}}/{{site.sdkInfo.channel}}/dart-js_interop/JSAnyUtilityExtension/isA.html
254
277
[ #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