invalid_runtime_check_with_js_interop_types
Avoid runtime type tests with JS interop types where the result may not be platform-consistent.
This rule is currently experimental and not yet available in a stable SDK.
Details
#DON'T use 'is' checks where the type is a JS interop type.
DON'T use 'is' checks where the type is a generic Dart type that has JS interop type arguments.
DON'T use 'is' checks with a JS interop value.
'dart:js_interop' types have runtime types that are different based on whether you are compiling to JS or to Wasm. Therefore, runtime type checks may result in different behavior. Runtime checks also do not necessarily check that a JS interop value is a particular JavaScript type.
BAD:
extension type HTMLElement(JSObject o) {}
extension type HTMLDivElement(JSObject o) implements HTMLElement {}
void compute(JSAny a, bool b, List<JSObject> lo, List<String> ls, JSObject o,
HTMLElement e) {
a is String; // LINT, checking that a JS value is a Dart type
b is JSBoolean; // LINT, checking that a Dart value is a JS type
a is JSString; // LINT, checking that a JS value is a different JS interop
// type
o is JSNumber; // LINT, checking that a JS value is a different JS interop
// type
lo is List<String>; // LINT, JS interop type argument and Dart type argument
// are incompatible
ls is List<JSString>; // LINT, Dart type argument and JS interop type argument
// are incompatible
lo is List<JSArray>; // LINT, comparing JS interop type argument with
// different JS interop type argument
lo is List<JSNumber>; // LINT, comparing JS interop type argument with
// different JS interop type argument
o is HTMLElement; // LINT, true because both are JSObjects but doesn't check
// that it's a JS HTMLElement
e is HTMLDivElement; // LINT, true because both are JSObjects but doesn't
// check that it's a JS HTMLDivElement
}
Prefer using JS interop helpers like 'isA' from 'dart:js_interop' to check the underlying type of JS interop values.
GOOD:
extension type HTMLElement(JSObject o) implements JSObject {}
extension type HTMLDivElement(JSObject o) implements HTMLElement {}
void compute(JSAny a, List<JSAny> l, JSObject o, HTMLElement e) {
a.isA<JSString>; // OK, uses JS interop to check it is a JS string
l[0].isA<JSString>; // OK, uses JS interop to check it is a JS string
o.isA<HTMLElement>(); // OK, uses JS interop to check `o` is an HTMLElement
e.isA<HTMLDivElement>(); // OK, uses JS interop to check `e` is an
// HTMLDivElement
}
DON'T use 'as' to cast a JS interop value to an unrelated Dart type or an unrelated Dart value to a JS interop type.
DON'T use 'as' to cast a JS interop value to a JS interop type represented by an incompatible 'dart:js_interop' type.
BAD:
extension type Window(JSObject o) {}
void compute(String s, JSBoolean b, Window w, List<String> l,
List<JSObject> lo) {
s as JSString; // LINT, casting Dart type to JS interop type
b as bool; // LINT, casting JS interop type to Dart type
b as JSNumber; // LINT, JSBoolean and JSNumber are incompatible
b as Window; // LINT, JSBoolean and JSObject are incompatible
w as JSBoolean; // LINT, JSObject and JSBoolean are incompatible
l as List<JSString>; // LINT, casting Dart value with Dart type argument to
// Dart type with JS interop type argument
lo as List<String>; // LINT, casting Dart value with JS interop type argument
// to Dart type with Dart type argument
lo as List<JSBoolean>; // LINT, casting Dart value with JS interop type
// argument to Dart type with incompatible JS interop
// type argument
}
Prefer using 'dart:js_interop' conversion methods to convert a JS interop value to a Dart value and vice versa.
GOOD:
extension type Window(JSObject o) {}
extension type Document(JSObject o) {}
void compute(String s, JSBoolean b, Window w, JSArray<JSString> a,
List<String> ls, JSObject o, List<JSAny> la) {
s.toJS; // OK, converts the Dart type to a JS type
b.toDart; // OK, converts the JS type to a Dart type
a.toDart; // OK, converts the JS type to a Dart type
w as Document; // OK, but no runtime check that `w` is a JS Document
ls.map((e) => e.toJS).toList(); // OK, converts the Dart types to JS types
o as JSArray<JSString>; // OK, JSObject and JSArray are compatible
la as List<JSString>; // OK, JSAny and JSString are compatible
(o as Object) as JSObject; // OK, Object is a supertype of JSAny
}
Usage
#To enable the invalid_runtime_check_with_js_interop_types
rule,
add invalid_runtime_check_with_js_interop_types
under linter > rules in your
analysis_options.yaml
file:
linter:
rules:
- invalid_runtime_check_with_js_interop_types
除非另有说明,文档之所提及适用于 Dart 3.5.0 版本,本页面最后更新时间: 2024-08-07。 查看文档源码 或者 报告页面问题。