CINXE.COM

JS types | Dart

<!doctype html><html lang="en"><head><meta charset="utf-8"><meta http-equiv="x-ua-compatible" content="ie=edge"><meta name="viewport" content="width=device-width,initial-scale=1"><script>!function(e,t,a,n){e[n]=e[n]||[],e[n].push({"gtm.start":(new Date).getTime(),event:"gtm.js"});var g=t.getElementsByTagName(a)[0],m=t.createElement(a);m.async=!0,m.src="https://www.googletagmanager.com/gtm.js?id=GTM-5VSZM5J",g.parentNode.insertBefore(m,g)}(window,document,"script","dataLayer")</script><meta name="description" content="Usage information about the core types in JS interop."><title>JS types | Dart</title><link rel="icon" sizes="64x64" href="/assets/img/logo/dart-64.png" eleventy:ignore><link href="/assets/img/touch-icon-iphone.png" rel="apple-touch-icon" eleventy:ignore><link href="/assets/img/touch-icon-ipad.png" rel="apple-touch-icon" sizes="152x152" eleventy:ignore><link href="/assets/img/touch-icon-iphone-retina.png" rel="apple-touch-icon" sizes="180x180" eleventy:ignore><link href="/assets/img/touch-icon-ipad-retina.png" rel="apple-touch-icon" sizes="167x167" eleventy:ignore><meta name="twitter:card" content="summary"><meta name="twitter:site" content="@dart_lang"><meta name="twitter:title" content="JS types"><meta name="twitter:description" content="Usage information about the core types in JS interop."><meta property="og:title" content="JS types"><meta property="og:description" content="Usage information about the core types in JS interop."><meta property="og:url" content="/interop/js-interop/js-types/"><meta property="og:image" content="/assets/img/logo/dart-logo-for-shares.png?2" eleventy:ignore><link rel="preconnect" href="https://fonts.googleapis.com"><link rel="preconnect" href="https://fonts.gstatic.com" crossorigin><link href="https://fonts.googleapis.com/css2?family=Google+Sans:wght@400;500;700&display=swap" rel="stylesheet"><link href="https://fonts.googleapis.com/css2?family=Google+Sans+Display:wght@400&display=swap" rel="stylesheet"><link href="https://fonts.googleapis.com/css2?family=Google+Sans+Mono:wght@400;500;700&display=swap" rel="stylesheet"><link href="https://fonts.googleapis.com/css2?family=Google+Sans+Text:wght@400;500;700&display=swap" rel="stylesheet"><link href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,GRAD@24,400,0..1,0" rel="stylesheet"><link rel="stylesheet" href="/assets/css/main.css?v=3"><script src="/assets/js/os-tabs.js?v=3"></script><script src="/assets/js/main.js?v=3"></script><script>!function(e,a,t,n,c,o,s){e.GoogleAnalyticsObject=c,e[c]=e[c]||function(){(e[c].q=e[c].q||[]).push(arguments)},e[c].l=1*new Date,o=a.createElement(t),s=a.getElementsByTagName(t)[0],o.async=1,o.src="//www.google-analytics.com/analytics.js",s.parentNode.insertBefore(o,s)}(window,document,"script",0,"ga"),ga("create","UA-26406144-4","auto"),ga("send","pageview")</script></head><body class="default.html"><a id="skip-to-main" class="filled-button" href="#site-content-title" tabindex="1">Skip to main content</a><section id="cookie-notice"><div class="container"><p>dart.dev uses cookies from Google to deliver and enhance the quality of its services and to analyze traffic.</p><div class="button-group"><a class="text-button" href="https://policies.google.com/technologies/cookies" target="_blank" rel="noopener">Learn more</a> <button id="cookie-consent" class="filled-button">OK, got it</button></div></div></section><noscript><iframe src="https://www.googletagmanager.com/ns.html?id=GTM-5VSZM5J" height="0" width="0" style="display:none;visibility:hidden"></iframe></noscript><div id="site-banner" role="alert"><p>Announcing Dart 3.7! Find out about updates to the language, analyzer, pub.dev, and more, in the <a href="https://medium.com/dartlang/announcing-dart-3-7-bf864a1b195c" target="_blank">blog post</a>.</p></div><header id="site-header"><nav id="mainnav"><div id="menu-toggle"><span class="material-symbols" title="Toggle side navigation menu." aria-label="Toggle side navigation menu." type="button">menu</span></div><a href="/" class="brand" title="Dart"><img src="/assets/img/logo/logo-white-text.svg" alt="Dart"></a><ul class="navbar"><li><a href="/overview" class="nav-link">Overview</a></li><li class="mainnav__get-started"><a href="/docs" class="nav-link"><span>Docs</span></a></li><li><a href="/community" class="nav-link">Community</a></li><li><a href="/#try-dart" class="nav-link">Try Dart</a></li><li><a href="/get-dart" class="nav-link">Get Dart</a></li><li class="searchfield"><form action="/search" class="site-header-search form-inline" id="cse-search-box"><input type="hidden" name="cx" value="011220921317074318178:_yy-tmb5t_i"> <input type="hidden" name="ie" value="UTF-8"> <input type="hidden" name="hl" value="en"> <input class="site-header-searchfield form-control search-field" type="search" name="q" id="search-main" autocomplete="off" placeholder="Search" aria-label="Search"></form></li></ul></nav></header><div id="site-below-header"><div id="site-main-row"><div id="sidenav"><form action="/search/" class="site-header-search form-inline"><input class="site-header-searchfield form-control search-field" type="search" name="q" id="search-side" autocomplete="off" placeholder="Search" aria-label="Search"></form><ul class="navbar-nav"><li aria-hidden="true"><div class="sidenav-divider"></div></li><li class="nav-item"><a href="/overview" class="nav-link">Overview</a></li><li class="nav-item"><a href="/community" class="nav-link">Community</a></li><li class="nav-item"><a href="https://dartpad.dev" class="nav-link">Try Dart</a></li><li class="nav-item"><a href="/get-dart" class="nav-link">Get Dart</a></li><li class="nav-item"><a href="/docs" class="nav-link">Docs</a></li><li aria-hidden="true"><div class="sidenav-divider"></div></li></ul><ul class="nav"><li class="nav-item"><button class="nav-link collapsed collapsible" data-toggle="collapse" data-target="#-sidenav-1" role="button" aria-expanded="false" aria-controls="-sidenav-1"><span>Language</span> <span class="material-symbols expander" aria-hidden="true">expand_more</span></button><ul class="nav collapse" id="-sidenav-1"><li class="nav-item"><a class="nav-link" href="/language"><div><span>Introduction</span></div></a></li><li class="nav-item"><button class="nav-link collapsible collapsed" data-toggle="collapse" data-target="#-sidenav-1-2" role="button" aria-expanded="false" aria-controls="-sidenav-1-2"><span>Syntax basics</span> <span class="material-symbols expander" aria-hidden="true">expand_more</span></button><ul class="nav collapse" id="-sidenav-1-2"><li class="nav-item"><a class="nav-link" href="/language/variables"><div><span>Variables</span></div></a></li><li class="nav-item"><a class="nav-link" href="/language/operators"><div><span>Operators</span></div></a></li><li class="nav-item"><a class="nav-link" href="/language/comments"><div><span>Comments</span></div></a></li><li class="nav-item"><a class="nav-link" href="/language/metadata"><div><span>Metadata</span></div></a></li><li class="nav-item"><a class="nav-link" href="/language/libraries"><div><span>Libraries & imports</span></div></a></li><li class="nav-item"><a class="nav-link" href="/language/keywords"><div><span>Keywords</span></div></a></li></ul></li><li class="nav-item"><button class="nav-link collapsible collapsed" data-toggle="collapse" data-target="#-sidenav-1-3" role="button" aria-expanded="false" aria-controls="-sidenav-1-3"><span>Types</span> <span class="material-symbols expander" aria-hidden="true">expand_more</span></button><ul class="nav collapse" id="-sidenav-1-3"><li class="nav-item"><a class="nav-link" href="/language/built-in-types"><div><span>Built-in types</span></div></a></li><li class="nav-item"><a class="nav-link" href="/language/records"><div><span>Records</span></div></a></li><li class="nav-item"><a class="nav-link" href="/language/collections"><div><span>Collections</span></div></a></li><li class="nav-item"><a class="nav-link" href="/language/generics"><div><span>Generics</span></div></a></li><li class="nav-item"><a class="nav-link" href="/language/typedefs"><div><span>Typedefs</span></div></a></li><li class="nav-item"><a class="nav-link" href="/language/type-system"><div><span>Type system</span></div></a></li></ul></li><li class="nav-item"><button class="nav-link collapsible collapsed" data-toggle="collapse" data-target="#-sidenav-1-4" role="button" aria-expanded="false" aria-controls="-sidenav-1-4"><span>Patterns</span> <span class="material-symbols expander" aria-hidden="true">expand_more</span></button><ul class="nav collapse" id="-sidenav-1-4"><li class="nav-item"><a class="nav-link" href="/language/patterns"><div><span>Overview & usage</span></div></a></li><li class="nav-item"><a class="nav-link" href="/language/pattern-types"><div><span>Pattern types</span></div></a></li><li class="nav-item"><a class="nav-link" href="https://codelabs.developers.google.com/codelabs/dart-patterns-records" target="_blank" rel="noopener"><div><span>Applied tutorial</span><span class="material-symbols" aria-hidden="true">open_in_new</span></div></a></li></ul></li><li class="nav-item"><a class="nav-link" href="/language/functions"><div><span>Functions</span></div></a></li><li class="nav-item"><button class="nav-link collapsible collapsed" data-toggle="collapse" data-target="#-sidenav-1-6" role="button" aria-expanded="false" aria-controls="-sidenav-1-6"><span>Control flow</span> <span class="material-symbols expander" aria-hidden="true">expand_more</span></button><ul class="nav collapse" id="-sidenav-1-6"><li class="nav-item"><a class="nav-link" href="/language/loops"><div><span>Loops</span></div></a></li><li class="nav-item"><a class="nav-link" href="/language/branches"><div><span>Branches</span></div></a></li><li class="nav-item"><a class="nav-link" href="/language/error-handling"><div><span>Error handling</span></div></a></li></ul></li><li class="nav-item"><button class="nav-link collapsible collapsed" data-toggle="collapse" data-target="#-sidenav-1-7" role="button" aria-expanded="false" aria-controls="-sidenav-1-7"><span>Classes & objects</span> <span class="material-symbols expander" aria-hidden="true">expand_more</span></button><ul class="nav collapse" id="-sidenav-1-7"><li class="nav-item"><a class="nav-link" href="/language/classes"><div><span>Classes</span></div></a></li><li class="nav-item"><a class="nav-link" href="/language/constructors"><div><span>Constructors</span></div></a></li><li class="nav-item"><a class="nav-link" href="/language/methods"><div><span>Methods</span></div></a></li><li class="nav-item"><a class="nav-link" href="/language/extend"><div><span>Extend a class</span></div></a></li><li class="nav-item"><a class="nav-link" href="/language/mixins"><div><span>Mixins</span></div></a></li><li class="nav-item"><a class="nav-link" href="/language/enums"><div><span>Enums</span></div></a></li><li class="nav-item"><a class="nav-link" href="/language/extension-methods"><div><span>Extension methods</span></div></a></li><li class="nav-item"><a class="nav-link" href="/language/extension-types"><div><span>Extension types</span></div></a></li><li class="nav-item"><a class="nav-link" href="/language/callable-objects"><div><span>Callable objects</span></div></a></li></ul></li><li class="nav-item"><button class="nav-link collapsible collapsed" data-toggle="collapse" data-target="#-sidenav-1-8" role="button" aria-expanded="false" aria-controls="-sidenav-1-8"><span>Class modifiers</span> <span class="material-symbols expander" aria-hidden="true">expand_more</span></button><ul class="nav collapse" id="-sidenav-1-8"><li class="nav-item"><a class="nav-link" href="/language/class-modifiers"><div><span>Overview & usage</span></div></a></li><li class="nav-item"><a class="nav-link" href="/language/class-modifiers-for-apis"><div><span>Class modifiers for API maintainers</span></div></a></li><li class="nav-item"><a class="nav-link" href="/language/modifier-reference"><div><span>Reference</span></div></a></li></ul></li><li class="nav-item"><button class="nav-link collapsible collapsed" data-toggle="collapse" data-target="#-sidenav-1-9" role="button" aria-expanded="false" aria-controls="-sidenav-1-9"><span>Concurrency</span> <span class="material-symbols expander" aria-hidden="true">expand_more</span></button><ul class="nav collapse" id="-sidenav-1-9"><li class="nav-item"><a class="nav-link" href="/language/concurrency"><div><span>Overview</span></div></a></li><li class="nav-item"><a class="nav-link" href="/language/async"><div><span>Asynchronous support</span></div></a></li><li class="nav-item"><a class="nav-link" href="/language/isolates"><div><span>Isolates</span></div></a></li></ul></li><li class="nav-item"><button class="nav-link collapsible collapsed" data-toggle="collapse" data-target="#-sidenav-1-10" role="button" aria-expanded="false" aria-controls="-sidenav-1-10"><span>Null safety</span> <span class="material-symbols expander" aria-hidden="true">expand_more</span></button><ul class="nav collapse" id="-sidenav-1-10"><li class="nav-item"><a class="nav-link" href="/null-safety"><div><span>Sound null safety</span></div></a></li><li class="nav-item"><a class="nav-link" href="/null-safety/migration-guide"><div><span>Migrating to null safety</span></div></a></li><li class="nav-item"><a class="nav-link" href="/null-safety/understanding-null-safety"><div><span>Understanding null safety</span></div></a></li><li class="nav-item"><a class="nav-link" href="/null-safety/unsound-null-safety"><div><span>Unsound null safety</span></div></a></li><li class="nav-item"><a class="nav-link" href="/null-safety/faq"><div><span>FAQ</span></div></a></li></ul></li></ul></li><li class="nav-item"><button class="nav-link collapsed collapsible" data-toggle="collapse" data-target="#-sidenav-2" role="button" aria-expanded="false" aria-controls="-sidenav-2"><span>Core libraries</span> <span class="material-symbols expander" aria-hidden="true">expand_more</span></button><ul class="nav collapse" id="-sidenav-2"><li class="nav-item"><a class="nav-link" href="/libraries"><div><span>Overview</span></div></a></li><li class="nav-item"><a class="nav-link" href="/libraries/dart-core"><div><span>dart:core</span></div></a></li><li class="nav-item"><a class="nav-link" href="/libraries/dart-async"><div><span>dart:async</span></div></a></li><li class="nav-item"><a class="nav-link" href="/libraries/dart-math"><div><span>dart:math</span></div></a></li><li class="nav-item"><a class="nav-link" href="/libraries/dart-convert"><div><span>dart:convert</span></div></a></li><li class="nav-item"><a class="nav-link" href="/libraries/dart-io"><div><span>dart:io</span></div></a></li><li class="nav-item"><a class="nav-link" href="/interop/js-interop"><div><span>dart:js_interop</span></div></a></li><div class="sidenav-divider"></div><li class="nav-item"><a class="nav-link" href="/libraries/collections/iterables"><div><span>Iterable collections</span></div></a></li><li class="nav-item"><button class="nav-link collapsible collapsed" data-toggle="collapse" data-target="#-sidenav-2-10" role="button" aria-expanded="false" aria-controls="-sidenav-2-10"><span>Asynchronous programming</span> <span class="material-symbols expander" aria-hidden="true">expand_more</span></button><ul class="nav collapse" id="-sidenav-2-10"><li class="nav-item"><a class="nav-link" href="/libraries/async/async-await"><div><span>Tutorial</span></div></a></li><li class="nav-item"><a class="nav-link" href="/libraries/async/futures-error-handling"><div><span>Futures and error handling</span></div></a></li><li class="nav-item"><a class="nav-link" href="/libraries/async/using-streams"><div><span>Using streams</span></div></a></li><li class="nav-item"><a class="nav-link" href="/libraries/async/creating-streams"><div><span>Creating streams</span></div></a></li></ul></li></ul></li><li class="nav-item"><button class="nav-link collapsed collapsible" data-toggle="collapse" data-target="#-sidenav-3" role="button" aria-expanded="false" aria-controls="-sidenav-3"><span>Effective Dart</span> <span class="material-symbols expander" aria-hidden="true">expand_more</span></button><ul class="nav collapse" id="-sidenav-3"><li class="nav-item"><a class="nav-link" href="/effective-dart"><div><span>Overview</span></div></a></li><li class="nav-item"><a class="nav-link" href="/effective-dart/style"><div><span>Style</span></div></a></li><li class="nav-item"><a class="nav-link" href="/effective-dart/documentation"><div><span>Documentation</span></div></a></li><li class="nav-item"><a class="nav-link" href="/effective-dart/usage"><div><span>Usage</span></div></a></li><li class="nav-item"><a class="nav-link" href="/effective-dart/design"><div><span>Design</span></div></a></li></ul></li><li class="nav-item"><button class="nav-link collapsed collapsible" data-toggle="collapse" data-target="#-sidenav-4" role="button" aria-expanded="false" aria-controls="-sidenav-4"><span>Packages</span> <span class="material-symbols expander" aria-hidden="true">expand_more</span></button><ul class="nav collapse" id="-sidenav-4"><li class="nav-item"><a class="nav-link" href="/tools/pub/packages"><div><span>How to use packages</span></div></a></li><li class="nav-item"><a class="nav-link" href="/resources/useful-packages"><div><span>Commonly used packages</span></div></a></li><li class="nav-item"><a class="nav-link" href="/tools/pub/create-packages"><div><span>Creating packages</span></div></a></li><li class="nav-item"><a class="nav-link" href="/tools/pub/publishing"><div><span>Publishing packages</span></div></a></li><li class="nav-item"><a class="nav-link" href="/tools/pub/writing-package-pages"><div><span>Writing package pages</span></div></a></li><li class="nav-item"><a class="nav-link" href="/tools/pub/workspaces"><div><span>Workspaces (monorepo support)</span></div></a></li><li class="nav-item"><button class="nav-link collapsible collapsed" data-toggle="collapse" data-target="#-sidenav-4-7" role="button" aria-expanded="false" aria-controls="-sidenav-4-7"><span>Package reference</span> <span class="material-symbols expander" aria-hidden="true">expand_more</span></button><ul class="nav collapse" id="-sidenav-4-7"><li class="nav-item"><a class="nav-link" href="/tools/pub/dependencies"><div><span>Dependencies</span></div></a></li><li class="nav-item"><a class="nav-link" href="/tools/pub/glossary"><div><span>Glossary</span></div></a></li><li class="nav-item"><a class="nav-link" href="/tools/pub/package-layout"><div><span>Package layout conventions</span></div></a></li><li class="nav-item"><a class="nav-link" href="/tools/pub/environment-variables"><div><span>Pub environment variables</span></div></a></li><li class="nav-item"><a class="nav-link" href="/tools/pub/pubspec"><div><span>Pubspec file</span></div></a></li><li class="nav-item"><a class="nav-link" href="/tools/pub/troubleshoot"><div><span>Troubleshooting pub</span></div></a></li><li class="nav-item"><a class="nav-link" href="/tools/pub/verified-publishers"><div><span>Verified publishers</span></div></a></li><li class="nav-item"><a class="nav-link" href="/tools/pub/security-advisories"><div><span>Security advisories</span></div></a></li><li class="nav-item"><a class="nav-link" href="/tools/pub/versioning"><div><span>Versioning</span></div></a></li><li class="nav-item"><a class="nav-link" href="/tools/pub/custom-package-repositories"><div><span>Custom package repositories</span></div></a></li></ul></li><li class="nav-item"><a class="nav-link" href="/tools/pub/private-files"><div><span>What not to commit</span></div></a></li></ul></li><li class="nav-item"><button class="nav-link collapsed collapsible" data-toggle="collapse" data-target="#-sidenav-5" role="button" aria-expanded="false" aria-controls="-sidenav-5"><span>Development</span> <span class="material-symbols expander" aria-hidden="true">expand_more</span></button><ul class="nav collapse" id="-sidenav-5"><li class="nav-item"><a class="nav-link" href="/libraries/serialization/json"><div><span>JSON serialization</span></div></a></li><li class="nav-item"><a class="nav-link" href="/resources/language/number-representation"><div><span>Number representation</span></div></a></li><li class="nav-item"><a class="nav-link" href="/resources/google-apis"><div><span>Google APIs</span></div></a></li><li class="nav-item"><a class="nav-link" href="/multiplatform-apps"><div><span>Multi-platform apps</span></div></a></li><li class="nav-item"><button class="nav-link collapsible collapsed" data-toggle="collapse" data-target="#-sidenav-5-5" role="button" aria-expanded="false" aria-controls="-sidenav-5-5"><span>Command-line & server apps</span> <span class="material-symbols expander" aria-hidden="true">expand_more</span></button><ul class="nav collapse" id="-sidenav-5-5"><li class="nav-item"><a class="nav-link" href="/server"><div><span>Overview</span></div></a></li><li class="nav-item"><a class="nav-link" href="/tutorials/server/get-started"><div><span>Get started</span></div></a></li><li class="nav-item"><a class="nav-link" href="/tutorials/server/cmdline"><div><span>Write command-line apps</span></div></a></li><li class="nav-item"><a class="nav-link" href="/tutorials/server/fetch-data"><div><span>Fetch data from the internet</span></div></a></li><li class="nav-item"><a class="nav-link" href="/tutorials/server/httpserver"><div><span>Write HTTP servers</span></div></a></li><li class="nav-item"><a class="nav-link" href="/server/libraries"><div><span>Libraries & packages</span></div></a></li><li class="nav-item"><a class="nav-link" href="/server/google-cloud"><div><span>Google Cloud</span></div></a></li></ul></li><li class="nav-item"><button class="nav-link collapsible collapsed" data-toggle="collapse" data-target="#-sidenav-5-6" role="button" aria-expanded="false" aria-controls="-sidenav-5-6"><span>Web apps</span> <span class="material-symbols expander" aria-hidden="true">expand_more</span></button><ul class="nav collapse" id="-sidenav-5-6"><li class="nav-item"><a class="nav-link" href="/web"><div><span>Overview</span></div></a></li><li class="nav-item"><a class="nav-link" href="/web/get-started"><div><span>Get started</span></div></a></li><li class="nav-item"><a class="nav-link" href="/web/deployment"><div><span>Deployment</span></div></a></li><li class="nav-item"><a class="nav-link" href="/web/libraries"><div><span>Libraries & packages</span></div></a></li><li class="nav-item"><a class="nav-link" href="/web/wasm"><div><span>Wasm compilation</span></div></a></li></ul></li><li class="nav-item"><a class="nav-link" href="/libraries/core/environment-declarations"><div><span>Environment declarations</span></div></a></li></ul></li><li class="nav-item"><button class="nav-link active collapsible" data-toggle="collapse" data-target="#-sidenav-6" role="button" aria-expanded="true" aria-controls="-sidenav-6"><span>Interoperability</span> <span class="material-symbols expander" aria-hidden="true">expand_more</span></button><ul class="nav collapse show" id="-sidenav-6"><li class="nav-item"><a class="nav-link" href="/interop/c-interop"><div><span>C interop</span></div></a></li><li class="nav-item"><a class="nav-link" href="/interop/objective-c-interop"><div><span>Objective-C & Swift interop</span></div></a></li><li class="nav-item"><a class="nav-link" href="/interop/java-interop"><div><span>Java & Kotlin interop</span></div></a></li><li class="nav-item"><button class="nav-link active collapsible" data-toggle="collapse" data-target="#-sidenav-6-4" role="button" aria-expanded="true" aria-controls="-sidenav-6-4"><span>JavaScript interop</span> <span class="material-symbols expander" aria-hidden="true">expand_more</span></button><ul class="nav collapse show" id="-sidenav-6-4"><li class="nav-item"><a class="nav-link" href="/interop/js-interop"><div><span>Overview</span></div></a></li><li class="nav-item"><a class="nav-link" href="/interop/js-interop/usage"><div><span>Usage</span></div></a></li><li class="nav-item"><a class="nav-link active" href="/interop/js-interop/js-types"><div><span>JS types</span></div></a></li><li class="nav-item"><a class="nav-link" href="/interop/js-interop/tutorials"><div><span>Tutorials</span></div></a></li><li class="nav-item"><a class="nav-link" href="/interop/js-interop/past-js-interop"><div><span>Past JS interop</span></div></a></li><div class="sidenav-divider"></div><li class="nav-item"><a class="nav-link" href="/interop/js-interop/package-web"><div><span>Web interop</span></div></a></li></ul></li></ul></li><li class="nav-item"><button class="nav-link collapsed collapsible" data-toggle="collapse" data-target="#-sidenav-7" role="button" aria-expanded="false" aria-controls="-sidenav-7"><span>Tools & techniques</span> <span class="material-symbols expander" aria-hidden="true">expand_more</span></button><ul class="nav collapse" id="-sidenav-7"><li class="nav-item"><a class="nav-link" href="/tools"><div><span>Overview</span></div></a></li><li class="nav-item"><button class="nav-link collapsible collapsed" data-toggle="collapse" data-target="#-sidenav-7-2" role="button" aria-expanded="false" aria-controls="-sidenav-7-2"><span>Editors & debuggers</span> <span class="material-symbols expander" aria-hidden="true">expand_more</span></button><ul class="nav collapse" id="-sidenav-7-2"><li class="nav-item"><a class="nav-link" href="/tools/jetbrains-plugin"><div><span>IntelliJ & Android Studio</span></div></a></li><li class="nav-item"><a class="nav-link" href="/tools/vs-code"><div><span>VS Code</span></div></a></li><li class="nav-item"><a class="nav-link" href="/tools/dart-devtools"><div><span>Dart DevTools</span></div></a></li><li class="nav-item"><button class="nav-link collapsible collapsed" data-toggle="collapse" data-target="#-sidenav-7-2-4" role="button" aria-expanded="false" aria-controls="-sidenav-7-2-4"><span>DartPad</span> <span class="material-symbols expander" aria-hidden="true">expand_more</span></button><ul class="nav collapse" id="-sidenav-7-2-4"><li class="nav-item"><a class="nav-link" href="/tools/dartpad"><div><span>Overview</span></div></a></li><li class="nav-item"><a class="nav-link" href="/tools/dartpad/troubleshoot"><div><span>Troubleshooting DartPad</span></div></a></li></ul></li></ul></li><li class="nav-item"><button class="nav-link collapsible collapsed" data-toggle="collapse" data-target="#-sidenav-7-3" role="button" aria-expanded="false" aria-controls="-sidenav-7-3"><span>Command-line tools</span> <span class="material-symbols expander" aria-hidden="true">expand_more</span></button><ul class="nav collapse" id="-sidenav-7-3"><li class="nav-item"><button class="nav-link collapsible" data-toggle="collapse" data-target="#-sidenav-7-3-1" role="button" aria-expanded="true" aria-controls="-sidenav-7-3-1"><span>Dart SDK</span> <span class="material-symbols expander" aria-hidden="true">expand_more</span></button><ul class="nav collapse show" id="-sidenav-7-3-1"><li class="nav-item"><a class="nav-link" href="/tools/sdk"><div><span>Overview</span></div></a></li><li class="nav-item"><a class="nav-link" href="/tools/dart-tool"><div><span>dart</span></div></a></li><li class="nav-item"><a class="nav-link" href="/tools/dart-analyze"><div><span>dart analyze</span></div></a></li><li class="nav-item"><a class="nav-link" href="/tools/dart-compile"><div><span>dart compile</span></div></a></li><li class="nav-item"><a class="nav-link" href="/tools/dart-create"><div><span>dart create</span></div></a></li><li class="nav-item"><a class="nav-link" href="/tools/dart-doc"><div><span>dart doc</span></div></a></li><li class="nav-item"><a class="nav-link" href="/tools/dart-fix"><div><span>dart fix</span></div></a></li><li class="nav-item"><a class="nav-link" href="/tools/dart-format"><div><span>dart format</span></div></a></li><li class="nav-item"><a class="nav-link" href="/tools/dart-info"><div><span>dart info</span></div></a></li><li class="nav-item"><a class="nav-link" href="/tools/pub/cmd"><div><span>dart pub</span></div></a></li><li class="nav-item"><a class="nav-link" href="/tools/dart-run"><div><span>dart run</span></div></a></li><li class="nav-item"><a class="nav-link" href="/tools/dart-test"><div><span>dart test</span></div></a></li><li class="nav-item"><a class="nav-link" href="/tools/dartaotruntime"><div><span>dartaotruntime</span></div></a></li><li class="nav-item"><a class="nav-link" href="/tools/experiment-flags"><div><span>Experiment flags</span></div></a></li></ul></li><li class="nav-item"><button class="nav-link collapsible" data-toggle="collapse" data-target="#-sidenav-7-3-2" role="button" aria-expanded="true" aria-controls="-sidenav-7-3-2"><span>Other command-line tools</span> <span class="material-symbols expander" aria-hidden="true">expand_more</span></button><ul class="nav collapse show" id="-sidenav-7-3-2"><li class="nav-item"><a class="nav-link" href="/tools/build_runner"><div><span>build_runner</span></div></a></li><li class="nav-item"><a class="nav-link" href="/tools/webdev"><div><span>webdev</span></div></a></li></ul></li></ul></li><li class="nav-item"><button class="nav-link collapsible collapsed" data-toggle="collapse" data-target="#-sidenav-7-4" role="button" aria-expanded="false" aria-controls="-sidenav-7-4"><span>Static analysis</span> <span class="material-symbols expander" aria-hidden="true">expand_more</span></button><ul class="nav collapse" id="-sidenav-7-4"><li class="nav-item"><a class="nav-link" href="/tools/analysis"><div><span>Customizing static analysis</span></div></a></li><li class="nav-item"><a class="nav-link" href="/deprecated/sound-problems"><div><span>Fixing common type problems</span></div></a></li><li class="nav-item"><a class="nav-link" href="/tools/non-promotion-reasons"><div><span>Fixing type promotion failures</span></div></a></li><li class="nav-item"><a class="nav-link" href="/tools/linter-rules"><div><span>Linter rules</span></div></a></li><li class="nav-item"><a class="nav-link" href="/tools/diagnostic-messages"><div><span>Diagnostic messages</span></div></a></li></ul></li><li class="nav-item"><button class="nav-link collapsible collapsed" data-toggle="collapse" data-target="#-sidenav-7-5" role="button" aria-expanded="false" aria-controls="-sidenav-7-5"><span>Testing & optimization</span> <span class="material-symbols expander" aria-hidden="true">expand_more</span></button><ul class="nav collapse" id="-sidenav-7-5"><li class="nav-item"><a class="nav-link" href="/tools/testing"><div><span>Testing</span></div></a></li><li class="nav-item"><a class="nav-link" href="/web/debugging"><div><span>Debugging web apps</span></div></a></li></ul></li></ul></li><li aria-hidden="true"><div class="sidenav-divider"></div></li><li class="nav-item"><button class="nav-link collapsed collapsible" data-toggle="collapse" data-target="#-sidenav-9" role="button" aria-expanded="false" aria-controls="-sidenav-9"><span>Resources</span> <span class="material-symbols expander" aria-hidden="true">expand_more</span></button><ul class="nav collapse" id="-sidenav-9"><li class="nav-item"><a class="nav-link" href="/resources/dart-cheatsheet"><div><span>Language cheatsheet</span></div></a></li><li class="nav-item"><a class="nav-link" href="/resources/breaking-changes"><div><span>Breaking changes</span></div></a></li><li class="nav-item"><a class="nav-link" href="/resources/language/evolution"><div><span>Language evolution</span></div></a></li><li class="nav-item"><a class="nav-link" href="/resources/language/spec"><div><span>Language specification</span></div></a></li><li class="nav-item"><a class="nav-link" href="/resources/dart-3-migration"><div><span>Dart 3 migration guide</span></div></a></li><li class="nav-item"><button class="nav-link collapsible collapsed" data-toggle="collapse" data-target="#-sidenav-9-6" role="button" aria-expanded="false" aria-controls="-sidenav-9-6"><span>Coming from ...</span> <span class="material-symbols expander" aria-hidden="true">expand_more</span></button><ul class="nav collapse" id="-sidenav-9-6"><li class="nav-item"><a class="nav-link" href="/resources/coming-from/js-to-dart"><div><span>JavaScript to Dart</span></div></a></li><li class="nav-item"><a class="nav-link" href="/resources/coming-from/swift-to-dart"><div><span>Swift to Dart</span></div></a></li></ul></li><div class="sidenav-divider"></div><li class="nav-item"><a class="nav-link" href="/resources/faq"><div><span>FAQ</span></div></a></li><li class="nav-item"><a class="nav-link" href="/resources/glossary"><div><span>Glossary</span></div></a></li><li class="nav-item"><a class="nav-link" href="/resources/books"><div><span>Books</span></div></a></li><li class="nav-item"><a class="nav-link" href="/resources/videos"><div><span>Videos</span></div></a></li><li class="nav-item"><a class="nav-link" href="/tutorials"><div><span>Tutorials</span></div></a></li></ul></li><li class="nav-item"><button class="nav-link collapsible" data-toggle="collapse" data-target="#-sidenav-10" role="button" aria-expanded="true" aria-controls="-sidenav-10"><span>Related sites</span> <span class="material-symbols expander" aria-hidden="true">expand_more</span></button><ul class="nav collapse show" id="-sidenav-10"><li class="nav-item"><a class="nav-link" href="https://api.dart.dev" target="_blank" rel="noopener"><div><span>API reference</span><span class="material-symbols" aria-hidden="true">open_in_new</span></div></a></li><li class="nav-item"><a class="nav-link" href="https://medium.com/dartlang" target="_blank" rel="noopener"><div><span>Blog</span><span class="material-symbols" aria-hidden="true">open_in_new</span></div></a></li><li class="nav-item"><a class="nav-link" href="https://dartpad.dev" target="_blank" rel="noopener"><div><span>DartPad (online editor)</span><span class="material-symbols" aria-hidden="true">open_in_new</span></div></a></li><li class="nav-item"><a class="nav-link" href="https://flutter.dev" target="_blank" rel="noopener"><div><span>Flutter</span><span class="material-symbols" aria-hidden="true">open_in_new</span></div></a></li><li class="nav-item"><a class="nav-link" href="https://pub.dev" target="_blank" rel="noopener"><div><span>Package site</span><span class="material-symbols" aria-hidden="true">open_in_new</span></div></a></li></ul></li></ul></div><main id="page-content"><div id="site-toc--side" class="site-toc"><header class="site-toc__title">Contents</header><ul class="section-nav"><li class="toc-entry nav-item"><a class="nav-link" href="#type-hierarchy">Type hierarchy</a></li><li class="toc-entry nav-item"><a class="nav-link" href="#conversions">Conversions</a></li><li class="toc-entry nav-item"><a class="nav-link" href="#requirements-on-external-declarations-and-function-tojs">Requirements on external declarations and Function.toJS</a></li><li class="toc-entry nav-item"><a class="nav-link" href="#compatibility-type-checks-and-casts">Compatibility, type checks, and casts</a></li><li class="toc-entry nav-item"><a class="nav-link" href="#null-vs-undefined">null vs undefined</a></li><li class="toc-entry nav-item"><a class="nav-link" href="#jsboxeddartobject-vs-externaldartreference">JSBoxedDartObject vs ExternalDartReference</a></li></ul></div><article><div class="content"><div id="site-content-title"><h1>JS types</h1></div><div id="site-toc--inline" class="site-toc"><header class="site-toc__title">Contents</header><ul class="section-nav"><li class="toc-entry"><a href="#type-hierarchy">Type hierarchy</a></li><li class="toc-entry"><a href="#conversions">Conversions</a></li><li class="toc-entry"><a href="#requirements-on-external-declarations-and-function-tojs">Requirements on external declarations and Function.toJS</a></li><li class="toc-entry"><a href="#compatibility-type-checks-and-casts">Compatibility, type checks, and casts</a></li><li class="toc-entry"><a href="#null-vs-undefined">null vs undefined</a></li><li class="toc-entry"><a href="#jsboxeddartobject-vs-externaldartreference">JSBoxedDartObject vs ExternalDartReference</a></li></ul></div><p>Dart values and JS values belong to separate language domains. When compiling to <a href="/web/wasm">Wasm</a>, they execute in separate <em>runtimes</em> as well. As such, you should treat JS values as foreign types. To provide Dart types for JS values, <a href="https://api.dart.dev/dart-js_interop/dart-js_interop-library.html"><code>dart:js_interop</code></a> exposes a set of types prefixed with <code>JS</code> called &quot;JS types&quot;. These types are used to distinguish between Dart values and JS values at compile-time.</p><p>Importantly, these types are reified differently based on whether you compile to Wasm or JS. This means that their runtime type will differ, and therefore you <a href="#compatibility-type-checks-and-casts">can't use <code>is</code> checks and <code>as</code> casts</a>. In order to interact with and examine these JS values, you should use <a href="/language/functions#external"><code>external</code></a> interop members or <a href="#conversions">conversions</a>.</p><div class="header-wrapper"><h2 id="type-hierarchy">Type hierarchy</h2><a class="heading-link" href="#type-hierarchy" aria-label="Link to 'Type hierarchy' section">#</a></div><p>JS types form a natural type hierarchy:</p><ul><li>Top type: <code>JSAny</code>, which is any non-nullish JS value<ul><li>Primitives: <code>JSNumber</code>, <code>JSBoolean</code>, <code>JSString</code></li><li><code>JSSymbol</code></li><li><code>JSBigInt</code></li><li><code>JSObject</code>, which is any JS object<ul><li><code>JSFunction</code><ul><li><code>JSExportedDartFunction</code>, which represents a Dart callback that was converted to a JS function</li></ul></li><li><code>JSArray</code></li><li><code>JSPromise</code></li><li><code>JSDataView</code></li><li><code>JSTypedArray</code><ul><li>JS typed arrays like <code>JSUint8Array</code></li></ul></li><li><code>JSBoxedDartObject</code>, which allows users to box and pass Dart values opaquely within the same Dart runtime<ul><li>From Dart 3.4 onwards, the type <code>ExternalDartReference</code> in <code>dart:js_interop</code> also allows users to pass Dart values opaquely, but is <em>not</em> a JS type. Learn more about the tradeoffs between each option <a href="#jsboxeddartobject-vs-externaldartreference">here</a>.</li></ul></li></ul></li></ul></li></ul><p>You can find the definition of each type in the <a href="https://api.dart.dev/dart-js_interop/dart-js_interop-library.html#extension-types"><code>dart:js_interop</code> API docs</a>.</p><div class="header-wrapper"><h2 id="conversions">Conversions</h2><a class="heading-link" href="#conversions" aria-label="Link to 'Conversions' section">#</a></div><p>To use a value from one domain to another, you will likely want to <em>convert</em> the value to the corresponding type of the other domain. For example, you may want to convert a Dart <code>List&lt;JSString&gt;</code> into a JS array of strings, which is represented by the JS type <code>JSArray&lt;JSString&gt;</code>, so that you can pass the array to a JS interop API.</p><p>Dart supplies a number of conversion members on various Dart types and JS types to convert the values between the domains for you.</p><p>Members that convert values from Dart to JS usually start with <code>toJS</code>:</p><div class="code-block-wrapper language-dart"><div class="code-block-body"><span class="code-block-language" title="Language dart">dart</span><pre class="shiki dash-light" tabindex="0"><code><span class="line"><span style="color:#0468D7">String</span><span style="color:#222222"> str = </span><span style="color:#11796D">'hello world'</span><span style="color:#222222">;</span></span> <span class="line"><span style="color:#0468D7">JSString</span><span style="color:#222222"> jsStr = str.toJS;</span></span></code></pre></div></div><p>Members that convert values from JS to Dart usually start with <code>toDart</code>:</p><div class="code-block-wrapper language-dart"><div class="code-block-body"><span class="code-block-language" title="Language dart">dart</span><pre class="shiki dash-light" tabindex="0"><code><span class="line"><span style="color:#0468D7">JSNumber</span><span style="color:#222222"> jsNum = ...;</span></span> <span class="line"><span style="color:#0468D7">int</span><span style="color:#222222"> integer = jsNum.toDartInt;</span></span></code></pre></div></div><p>Not all JS types have a conversion, and not all Dart types have a conversion. Generally, the conversion table looks like the following:</p><div class="table-wrapper"><table class="table table-striped"><thead><tr><th><code>dart:js_interop</code> type</th><th>Dart type</th></tr></thead><tbody><tr><td><code>JSNumber</code>, <code>JSBoolean</code>, <code>JSString</code></td><td><code>num</code>, <code>int</code>, <code>double</code>, <code>bool</code>, <code>String</code></td></tr><tr><td><code>JSExportedDartFunction</code></td><td><code>Function</code></td></tr><tr><td><code>JSArray&lt;T extends JSAny?&gt;</code></td><td><code>List&lt;T extends JSAny?&gt;</code></td></tr><tr><td><code>JSPromise&lt;T extends JSAny?&gt;</code></td><td><code>Future&lt;T extends JSAny?&gt;</code></td></tr><tr><td>Typed arrays like <code>JSUint8Array</code></td><td>Typed lists from <code>dart:typed_data</code></td></tr><tr><td><code>JSBoxedDartObject</code></td><td>Opaque Dart value</td></tr><tr><td><code>ExternalDartReference</code></td><td>Opaque Dart value</td></tr></tbody></table></div><aside class="alert alert-warning"><div class="alert-header"><span class="material-symbols" aria-hidden="true">warning</span> <span>Warning</span></div><div class="alert-content"><p>Compiling to JavaScript vs <a href="/web/wasm">Wasm</a> can introduce inconsistencies in both performance and semantics for conversions. Conversions may have different costs depending on the compiler, so prefer to only convert values if you need to.</p><p>Conversions also may or may not produce a new value. This doesn’t matter for immutable values like numbers, but does matter for types like <code>List</code>. Depending on the implementation, a conversion to <code>JSArray</code> may return a reference, a proxy, or a clone of the original list. To avoid this, do not rely on any relation between the <code>List</code> and <code>JSArray</code> and only rely on their contents being the same. Typed array conversions have a similar limitation. Look up the specific conversion function for more details.</p></div></aside><div class="header-wrapper"><h2 id="requirements-on-external-declarations-and-function-tojs">Requirements on <code>external</code> declarations and <code>Function.toJS</code></h2><a class="heading-link" href="#requirements-on-external-declarations-and-function-tojs" aria-label="Link to 'Requirements on external declarations and Function.toJS' section">#</a></div><p>In order to ensure type safety and consistency, the compiler places requirements on what types can flow into and out of JS. Passing arbitrary Dart values into JS is not allowed. Instead, the compiler requires users to use a compatible interop type, <code>ExternalDartReference</code>, or a primitive, which would then be implicitly converted by the compiler. For example, these would be allowed:</p><div class="code-block-wrapper language-dart"><div class="code-block-body has-tag tag-good"><span class="code-block-tag">good</span><span class="code-block-language" title="Language dart">dart</span><pre class="shiki dash-light" tabindex="0"><code><span class="line"><span style="color:#D43324">@JS</span><span style="color:#222222">()</span></span> <span class="line"><span style="color:#D43324">external</span><span style="color:#D43324"> void</span><span style="color:#6200EE"> primitives</span><span style="color:#222222">(</span><span style="color:#0468D7">String</span><span style="color:#222222"> a, </span><span style="color:#0468D7">int</span><span style="color:#222222"> b, </span><span style="color:#0468D7">double</span><span style="color:#222222"> c, </span><span style="color:#0468D7">num</span><span style="color:#222222"> d, </span><span style="color:#0468D7">bool</span><span style="color:#222222"> e);</span></span></code></pre></div></div><div class="code-block-wrapper language-dart"><div class="code-block-body has-tag tag-good"><span class="code-block-tag">good</span><span class="code-block-language" title="Language dart">dart</span><pre class="shiki dash-light" tabindex="0"><code><span class="line"><span style="color:#D43324">@JS</span><span style="color:#222222">()</span></span> <span class="line"><span style="color:#D43324">external</span><span style="color:#0468D7"> JSArray</span><span style="color:#6200EE"> jsTypes</span><span style="color:#222222">(</span><span style="color:#0468D7">JSObject</span><span style="color:#222222"> _, </span><span style="color:#0468D7">JSString</span><span style="color:#222222"> __);</span></span></code></pre></div></div><div class="code-block-wrapper language-dart"><div class="code-block-body has-tag tag-good"><span class="code-block-tag">good</span><span class="code-block-language" title="Language dart">dart</span><pre class="shiki dash-light" tabindex="0"><code><span class="line"><span style="color:#D43324">extension type</span><span style="color:#0468D7"> InteropType</span><span style="color:#222222">(</span><span style="color:#0468D7">JSObject</span><span style="color:#222222"> _) </span><span style="color:#D43324">implements</span><span style="color:#0468D7"> JSObject</span><span style="color:#222222"> {}</span></span> <span class="line"></span> <span class="line"><span style="color:#D43324">@JS</span><span style="color:#222222">()</span></span> <span class="line"><span style="color:#D43324">external</span><span style="color:#0468D7"> InteropType</span><span style="color:#D43324"> get</span><span style="color:#222222"> interopType;</span></span></code></pre></div></div><div class="code-block-wrapper language-dart"><div class="code-block-body has-tag tag-good"><span class="code-block-tag">good</span><span class="code-block-language" title="Language dart">dart</span><pre class="shiki dash-light" tabindex="0"><code><span class="line"><span style="color:#D43324">@JS</span><span style="color:#222222">()</span></span> <span class="line"><span style="color:#D43324">external</span><span style="color:#D43324"> void</span><span style="color:#6200EE"> externalDartReference</span><span style="color:#222222">(</span><span style="color:#0468D7">ExternalDartReference</span><span style="color:#222222"> _);</span></span></code></pre></div></div><p>Whereas these would return an error:</p><div class="code-block-wrapper language-dart"><div class="code-block-body has-tag tag-bad"><span class="code-block-tag">bad</span><span class="code-block-language" title="Language dart">dart</span><pre class="shiki dash-light" tabindex="0"><code><span class="line"><span style="color:#D43324">@JS</span><span style="color:#222222">()</span></span> <span class="line"><span style="color:#D43324">external</span><span style="color:#0468D7"> Function</span><span style="color:#D43324"> get</span><span style="color:#222222"> function;</span></span></code></pre></div></div><div class="code-block-wrapper language-dart"><div class="code-block-body has-tag tag-bad"><span class="code-block-tag">bad</span><span class="code-block-language" title="Language dart">dart</span><pre class="shiki dash-light" tabindex="0"><code><span class="line"><span style="color:#D43324">@JS</span><span style="color:#222222">()</span></span> <span class="line"><span style="color:#D43324">external</span><span style="color:#D43324"> set</span><span style="color:#6200EE"> list</span><span style="color:#222222">(</span><span style="color:#0468D7">List</span><span style="color:#222222"> _);</span></span></code></pre></div></div><p>These same requirements exist when you use <a href="https://api.dart.dev/dart-js_interop/FunctionToJSExportedDartFunction/toJS.html"><code>Function.toJS</code></a> to make a Dart function callable in JS. The values that flow into and out of this callback must be a compatible interop type or a primitive.</p><p>If you use a Dart primitive like <code>String</code>, an implicit conversion happens in the compiler to convert that value from a JS value to a Dart value. If performance is critical and you don’t need to examine the contents of the string, then using <code>JSString</code> instead to avoid the conversion cost may make sense like in the second example.</p><div class="header-wrapper"><h2 id="compatibility-type-checks-and-casts">Compatibility, type checks, and casts</h2><a class="heading-link" href="#compatibility-type-checks-and-casts" aria-label="Link to 'Compatibility, type checks, and casts' section">#</a></div><p>The runtime type of JS types may differ based on the compiler. This affects runtime type-checking and casts. Therefore, almost always avoid <code>is</code> checks where the value is an interop type or where the target type is an interop type:</p><div class="code-block-wrapper language-dart"><div class="code-block-body has-tag tag-bad"><span class="code-block-tag">bad</span><span class="code-block-language" title="Language dart">dart</span><pre class="shiki dash-light" tabindex="0"><code><span class="line"><span style="color:#D43324">void</span><span style="color:#6200EE"> f</span><span style="color:#222222">(</span><span style="color:#0468D7">JSAny</span><span style="color:#222222"> a) {</span></span> <span class="line"><span style="color:#D43324"> if</span><span style="color:#222222"> (a is </span><span style="color:#0468D7">String</span><span style="color:#222222">) { … }</span></span> <span class="line"><span style="color:#222222">}</span></span></code></pre></div></div><div class="code-block-wrapper language-dart"><div class="code-block-body has-tag tag-bad"><span class="code-block-tag">bad</span><span class="code-block-language" title="Language dart">dart</span><pre class="shiki dash-light" tabindex="0"><code><span class="line"><span style="color:#D43324">void</span><span style="color:#6200EE"> f</span><span style="color:#222222">(</span><span style="color:#0468D7">JSAny</span><span style="color:#222222"> a) {</span></span> <span class="line"><span style="color:#D43324"> if</span><span style="color:#222222"> (a is </span><span style="color:#0468D7">JSObject</span><span style="color:#222222">) { … }</span></span> <span class="line"><span style="color:#222222">}</span></span></code></pre></div></div><p>Also, avoid casts between Dart types and interop types:</p><div class="code-block-wrapper language-dart"><div class="code-block-body has-tag tag-bad"><span class="code-block-tag">bad</span><span class="code-block-language" title="Language dart">dart</span><pre class="shiki dash-light" tabindex="0"><code><span class="line"><span style="color:#D43324">void</span><span style="color:#6200EE"> f</span><span style="color:#222222">(</span><span style="color:#0468D7">JSString</span><span style="color:#222222"> s) {</span></span> <span class="line"><span style="color:#222222"> s </span><span style="color:#D43324">as</span><span style="color:#0468D7"> String</span><span style="color:#222222">;</span></span> <span class="line"><span style="color:#222222">}</span></span></code></pre></div></div><p>To type-check a JS value, use an interop member like <a href="https://api.dart.dev/dart-js_interop/JSAnyUtilityExtension/typeofEquals.html"><code>typeofEquals</code></a> or <a href="https://api.dart.dev/dart-js_interop/JSAnyUtilityExtension/instanceOfString.html"><code>instanceOfString</code></a> that examines the JS value itself:</p><div class="code-block-wrapper language-dart"><div class="code-block-body has-tag tag-good"><span class="code-block-tag">good</span><span class="code-block-language" title="Language dart">dart</span><pre class="shiki dash-light" tabindex="0"><code><span class="line"><span style="color:#D43324">void</span><span style="color:#6200EE"> f</span><span style="color:#222222">(</span><span style="color:#0468D7">JSAny</span><span style="color:#222222"> a) {</span></span> <span class="line"><span style="color:#6E6E70"> // Here `a` is verified to be a JS function, so the cast is okay.</span></span> <span class="line"><span style="color:#D43324"> if</span><span style="color:#222222"> (a.</span><span style="color:#6200EE">typeofEquals</span><span style="color:#222222">(</span><span style="color:#11796D">'function'</span><span style="color:#222222">)) {</span></span> <span class="line"><span style="color:#222222"> a </span><span style="color:#D43324">as</span><span style="color:#0468D7"> JSFunction</span><span style="color:#222222">;</span></span> <span class="line"><span style="color:#222222"> }</span></span> <span class="line"><span style="color:#222222">}</span></span></code></pre></div></div><p>From Dart 3.4 onwards, you can use the <a href="https://api.dart.dev/dart-js_interop/JSAnyUtilityExtension/isA.html"><code>isA</code></a> helper function to check whether a value is any interop type:</p><div class="code-block-wrapper language-dart"><div class="code-block-body has-tag tag-good"><span class="code-block-tag">good</span><span class="code-block-language" title="Language dart">dart</span><pre class="shiki dash-light" tabindex="0"><code><span class="line"><span style="color:#D43324">void</span><span style="color:#6200EE"> f</span><span style="color:#222222">(</span><span style="color:#0468D7">JSAny</span><span style="color:#222222"> a) {</span></span> <span class="line"><span style="color:#D43324"> if</span><span style="color:#222222"> (a.</span><span style="color:#6200EE">isA</span><span style="color:#222222">&#x3C;</span><span style="color:#0468D7">JSString</span><span style="color:#222222">>()) {} </span><span style="color:#6E6E70">// `typeofEquals('string')`</span></span> <span class="line"><span style="color:#D43324"> if</span><span style="color:#222222"> (a.</span><span style="color:#6200EE">isA</span><span style="color:#222222">&#x3C;</span><span style="color:#0468D7">JSArray</span><span style="color:#222222">>()) {} </span><span style="color:#6E6E70">// `instanceOfString('Array')`</span></span> <span class="line"><span style="color:#D43324"> if</span><span style="color:#222222"> (a.</span><span style="color:#6200EE">isA</span><span style="color:#222222">&#x3C;</span><span style="color:#0468D7">CustomInteropType</span><span style="color:#222222">>()) {} </span><span style="color:#6E6E70">// `instanceOfString('CustomInteropType')`</span></span> <span class="line"><span style="color:#222222">}</span></span></code></pre></div></div><p>Depending on the type parameter, it'll transform the call into the appropriate type-check for that type.</p><p>Dart may add lints to make runtime checks with JS interop types easier to avoid. See issue <a href="https://github.com/dart-lang/linter/issues/4841">#4841</a> for more details.</p><div class="header-wrapper"><h2 id="null-vs-undefined"><code>null</code> vs <code>undefined</code></h2><a class="heading-link" href="#null-vs-undefined" aria-label="Link to 'null vs undefined' section">#</a></div><p>JS has both a <code>null</code> and an <code>undefined</code> value. This is in contrast with Dart, which only has <code>null</code>. In order to make JS values more ergonomic to use, if an interop member were to return either JS <code>null</code> or <code>undefined</code>, the compiler maps these values to Dart <code>null</code>. Therefore a member like <code>value</code> in the following example can be interpreted as returning a JS object, JS <code>null</code>, or <code>undefined</code>:</p><div class="code-block-wrapper language-dart"><div class="code-block-body"><span class="code-block-language" title="Language dart">dart</span><pre class="shiki dash-light" tabindex="0"><code><span class="line"><span style="color:#D43324">@JS</span><span style="color:#222222">()</span></span> <span class="line"><span style="color:#D43324">external</span><span style="color:#0468D7"> JSObject</span><span style="color:#222222">? </span><span style="color:#D43324">get</span><span style="color:#222222"> value;</span></span></code></pre></div></div><p>If the return type was not declared as nullable, then the program will throw an error if the value returned was JS <code>null</code> or <code>undefined</code> to ensure soundness.</p><aside class="alert alert-warning"><div class="alert-header"><span class="material-symbols" aria-hidden="true">warning</span> <span>Warning</span></div><div class="alert-content"><p>There is a subtle inconsistency with regards to <code>undefined</code> between compiling to JS and <a href="/web/wasm">Wasm</a>. While compiling to JS <em>treats</em> <code>undefined</code> values as if they were Dart <code>null</code>, it doesn't actually <em>change</em> the value itself. If an interop member returns <code>undefined</code> and you pass that value back into JS, JS will see <code>undefined</code>, <em>not</em> <code>null</code>, when compiling to JS.</p><p>However, when compiling to Wasm, this is not the case, and the value will be <code>null</code> in JS. This is because the compiler implicitly <em>converts</em> the value to Dart <code>null</code> when compiling to Wasm, thereby losing information on whether the original value was JS <code>null</code> or <code>undefined</code>. Avoid writing code where this distinction matters by explicitly passing Dart <code>null</code> instead to an interop member.</p><p>Currently, there's no platform-consistent way to provide <code>undefined</code> to interop members or distinguish between JS <code>null</code> and <code>undefined</code> values, but this will likely change in the future. See <a href="https://github.com/dart-lang/sdk/issues/54025">#54025</a> for more details.</p></div></aside><div class="header-wrapper"><h2 id="jsboxeddartobject-vs-externaldartreference"><code>JSBoxedDartObject</code> vs <code>ExternalDartReference</code></h2><a class="heading-link" href="#jsboxeddartobject-vs-externaldartreference" aria-label="Link to 'JSBoxedDartObject vs ExternalDartReference' section">#</a></div><p>From Dart 3.4 onwards, both <a href="https://api.dart.dev/dart-js_interop/JSBoxedDartObject-extension-type.html"><code>JSBoxedDartObject</code></a> and <a href="https://api.dart.dev/dart-js_interop/ExternalDartReference-extension-type.html"><code>ExternalDartReference</code></a> can be used to pass opaque references to Dart <code>Object</code>s through JavaScript. However, <code>JSBoxedDartObject</code> wraps the opaque reference in a JavaScript object, while <code>ExternalDartReference</code> is the reference itself and therefore is not a JS type.</p><p>Use <code>JSBoxedDartObject</code> if you need a JS type or if you need extra checks to make sure Dart values don't get passed to another Dart runtime. For example, if the Dart object needs to be placed in a <code>JSArray</code> or passed to an API that accepts a <code>JSAny</code>, use <code>JSBoxedDartObject</code>. Use <code>ExternalDartReference</code> otherwise as it will be faster.</p><p>See <a href="https://api.dart.dev/dart-js_interop/ObjectToExternalDartReference/toExternalReference.html"><code>toExternalReference</code></a> and <a href="https://api.dart.dev/dart-js_interop/ExternalDartReferenceToObject/toDartObject.html"><code>toDartObject</code></a> to convert to and from an <code>ExternalDartReference</code>.</p><nav id="prev-next"><ul><li class="previous"><a href="/interop/js-interop/usage">&lang;&nbsp;&nbsp;Usage</a></li><li class="next"><a href="/interop/js-interop/tutorials">JS interop tutorials&nbsp;&nbsp;&rang;</a></li></ul></nav><p id="page-github-links"><span>Unless stated otherwise, the documentation on this site reflects Dart 3.7.0. Page last updated on 2025-01-22.</span> <a href="https://github.com/dart-lang/site-www/tree/main/src/content/interop/js-interop/js-types.md" target="_blank" rel="noopener">View source</a> <span>or </span><a href="https://github.com/dart-lang/site-www/issues/new?template=1_page_issue.yml&page-url=https://dart.dev/interop/js-interop/js-types/&page-source=https://github.com/dart-lang/site-www/tree/main/src/content/interop/js-interop/js-types.md" title="Report an issue with this page" target="_blank" rel="noopener">report an issue</a>.</p></div></article></main></div><footer id="page-footer"><div class="footer-section footer-main"><a href="/" class="brand" title="Dart"><img src="/assets/img/logo/logo-white-text.svg" alt="Dart" width="164"></a><div class="footer-social-links"><a href="https://medium.com/dartlang" target="_blank" rel="noopener" title="Dart's Medium publication"><svg><use href="/assets/img/social/medium.svg#medium"></use></svg> </a><a href="https://github.com/dart-lang" target="_blank" rel="noopener" title="Dart's GitHub organization"><svg><use href="/assets/img/social/github.svg#github"></use></svg> </a><a href="https://bsky.app/profile/dart.dev" target="_blank" rel="noopener" title="Dart's Bluesky profile"><svg><use href="/assets/img/social/bluesky.svg#bluesky"></use></svg> </a><a href="https://twitter.com/dart_lang" target="_blank" rel="noopener" title="Dart's X (Twitter) profile"><svg><use href="/assets/img/social/x.svg#x"></use></svg></a></div></div><div class="footer-section footer-tray"><div class="footer-licenses">Except as otherwise noted, this site is licensed under a <a href="https://creativecommons.org/licenses/by/4.0/">Creative Commons Attribution 4.0 International License</a>, and code samples are licensed under the <a href="https://opensource.org/licenses/BSD-3-Clause">3-Clause BSD License</a>.</div><div class="footer-utility-links"><ul><li><a href="/terms" title="Terms of use">Terms</a></li><li><a href="https://policies.google.com/privacy" target="_blank" rel="noopener" title="Privacy policy">Privacy</a></li><li><a href="/security" title="Security philosophy and practices">Security</a></li></ul></div></div></footer></div></body></html>

Pages: 1 2 3 4 5 6 7 8 9 10