CINXE.COM
Extension 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="Learn how to write a static-only interface for an existing type."><title>Extension 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="Extension types"><meta name="twitter:description" content="Learn how to write a static-only interface for an existing type."><meta property="og:title" content="Extension types"><meta property="og:description" content="Learn how to write a static-only interface for an existing type."><meta property="og:url" content="/language/extension-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=2"><script src="/assets/js/os-tabs.js?v=2"></script><script src="/assets/js/main.js?v=2"></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" 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="page-header" class="site-header"><nav id="mainnav" class="site-header"><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 active"><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 active collapsible" data-toggle="collapse" data-target="#-sidenav-1" role="button" aria-expanded="true" aria-controls="-sidenav-1"><span>Language</span> <span class="material-symbols expander" aria-hidden="true">expand_more</span></button><ul class="nav collapse show" 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 active collapsible" data-toggle="collapse" data-target="#-sidenav-1-7" role="button" aria-expanded="true" 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 show" 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 active" 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 collapsed collapsible" data-toggle="collapse" data-target="#-sidenav-6" role="button" aria-expanded="false" aria-controls="-sidenav-6"><span>Interoperability</span> <span class="material-symbols expander" aria-hidden="true">expand_more</span></button><ul class="nav collapse" 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 collapsible collapsed" data-toggle="collapse" data-target="#-sidenav-6-4" role="button" aria-expanded="false" 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" 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" 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="#syntax">Syntax</a><ul class="nav"><li class="toc-entry nav-item"><a class="nav-link" href="#declaration">Declaration</a></li><li class="toc-entry nav-item"><a class="nav-link" href="#constructors">Constructors</a></li><li class="toc-entry nav-item"><a class="nav-link" href="#members">Members</a></li><li class="toc-entry nav-item"><a class="nav-link" href="#implements">Implements</a></li></ul></li><li class="toc-entry nav-item"><a class="nav-link" href="#usage">Usage</a><ul class="nav"><li class="toc-entry nav-item"><a class="nav-link" href="#1-provide-an-extended-interface-to-an-existing-type">1. Provide an extended interface to an existing type</a></li><li class="toc-entry nav-item"><a class="nav-link" href="#2-provide-a-different-interface-to-an-existing-type">2. Provide a different interface to an existing type</a></li></ul></li><li class="toc-entry nav-item"><a class="nav-link" href="#type-considerations">Type considerations</a></li></ul></div><article><div class="content"><div id="site-content-title"><h1>Extension 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="#syntax">Syntax</a><ul><li class="toc-entry"><a href="#declaration">Declaration</a></li><li class="toc-entry"><a href="#constructors">Constructors</a></li><li class="toc-entry"><a href="#members">Members</a></li><li class="toc-entry"><a href="#implements">Implements</a></li></ul></li><li class="toc-entry"><a href="#usage">Usage</a><ul><li class="toc-entry"><a href="#1-provide-an-extended-interface-to-an-existing-type">1. Provide an extended interface to an existing type</a></li><li class="toc-entry"><a href="#2-provide-a-different-interface-to-an-existing-type">2. Provide a different interface to an existing type</a></li></ul></li><li class="toc-entry"><a href="#type-considerations">Type considerations</a></li></ul></div><p>An extension type is a compile-time abstraction that "wraps" an existing type with a different, static-only interface. They are a major component of <a href="/go/next-gen-js-interop">static JS interop</a> because they can easily modify an existing type's interface (crucial for any kind of interop) without incurring the cost of an actual wrapper.</p><p>Extension types enforce discipline on the set of operations (or interface) available to objects of an underlying type, called the <em>representation type</em>. When defining the interface of an extension type, you can choose to reuse some members of the representation type, omit others, replace others, and add new functionality.</p><p>The following example wraps the <code>int</code> type to create an extension type that only allows operations that make sense for ID numbers:</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">extension type</span><span style="color:#0468D7"> IdNumber</span><span style="color:#222222">(</span><span style="color:#0468D7">int</span><span style="color:#222222"> id) {</span></span> <span class="line"><span style="color:#6E6E70"> // Wraps the 'int' type's '<' operator:</span></span> <span class="line"><span style="color:#D43324"> operator</span><span style="color:#222222"> <(</span><span style="color:#0468D7">IdNumber</span><span style="color:#222222"> other) => id < other.id;</span></span> <span class="line"><span style="color:#6E6E70"> // Doesn't declare the '+' operator, for example,</span></span> <span class="line"><span style="color:#6E6E70"> // because addition does not make sense for ID numbers.</span></span> <span class="line"><span style="color:#222222">}</span></span> <span class="line"></span> <span class="line"><span style="color:#D43324">void</span><span style="color:#6200EE"> main</span><span style="color:#222222">() {</span></span> <span class="line"><span style="color:#6E6E70"> // Without the discipline of an extension type,</span></span> <span class="line"><span style="color:#6E6E70"> // 'int' exposes ID numbers to unsafe operations:</span></span> <span class="line"><span style="color:#0468D7"> int</span><span style="color:#222222"> myUnsafeId = </span><span style="color:#11796D">42424242</span><span style="color:#222222">;</span></span> <span class="line"><span style="color:#222222"> myUnsafeId = myUnsafeId + </span><span style="color:#11796D">10</span><span style="color:#222222">; </span><span style="color:#6E6E70">// This works, but shouldn't be allowed for IDs.</span></span> <span class="line"></span> <span class="line"><span style="color:#D43324"> var</span><span style="color:#222222"> safeId = </span><span style="color:#0468D7">IdNumber</span><span style="color:#222222">(</span><span style="color:#11796D">42424242</span><span style="color:#222222">);</span></span> <span class="line"><span style="color:#222222"> safeId + </span><span style="color:#11796D">10</span><span style="color:#222222">; </span><span style="color:#6E6E70">// Compile-time error: No '+' operator.</span></span> <span class="line"><span style="color:#222222"> myUnsafeId = safeId; </span><span style="color:#6E6E70">// Compile-time error: Wrong type.</span></span> <span class="line"><span style="color:#222222"> myUnsafeId = safeId </span><span style="color:#D43324">as</span><span style="color:#0468D7"> int</span><span style="color:#222222">; </span><span style="color:#6E6E70">// OK: Run-time cast to representation type.</span></span> <span class="line"><span style="color:#222222"> safeId < </span><span style="color:#0468D7">IdNumber</span><span style="color:#222222">(</span><span style="color:#11796D">42424241</span><span style="color:#222222">); </span><span style="color:#6E6E70">// OK: Uses wrapped '<' operator.</span></span> <span class="line"><span style="color:#222222">}</span></span></code></pre></div></div><aside class="alert alert-info"><div class="alert-header"><span class="material-symbols" aria-hidden="true">info</span> <span>Note</span></div><div class="alert-content"><p>Extension types serve the same purpose as <strong>wrapper classes</strong>, but don't require the creation of an extra run-time object, which can get expensive when you need to wrap lots of objects. Because extension types are static-only and compiled away at run time, they are essentially zero cost.</p><p><a href="/language/extension-methods"><strong>Extension methods</strong></a> (also known just as "extensions") are a static abstraction similar to extension types. However, an extension method adds functionality <em>directly</em> to every instance of its underlying type. Extension types are different; an extension type's interface <em>only</em> applies to expressions whose static type is that extension type. They are distinct from the interface of their underlying type by default.</p></div></aside><div class="header-wrapper"><h2 id="syntax">Syntax</h2><a class="heading-link" href="#syntax" aria-label="Link to 'Syntax' section">#</a></div><div class="header-wrapper"><h3 id="declaration">Declaration</h3><a class="heading-link" href="#declaration" aria-label="Link to 'Declaration' section">#</a></div><p>Define a new extension type with the <code>extension type</code> declaration and a name, followed by the <em>representation type declaration</em> in parenthesis:</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">extension type</span><span style="color:#0468D7"> E</span><span style="color:#222222">(</span><span style="color:#0468D7">int</span><span style="color:#222222"> i) {</span></span> <span class="line"><span style="color:#6E6E70"> // Define set of operations.</span></span> <span class="line"><span style="color:#222222">}</span></span></code></pre></div></div><p>The representation type declaration <code>(int i)</code> specifies that the underlying type of extension type <code>E</code> is <code>int</code>, and that the reference to the <em>representation object</em> is named <code>i</code>. The declaration also introduces:</p><ul><li>An implicit getter for the representation object with the representation type as the return type: <code>int get i</code>.</li><li>An implicit constructor: <code>E(int i) : i = i</code>.</li></ul><p>The representation object gives the extension type access to an object at the underlying type. The object is in scope in the extension type body, and you can access it using its name as a getter:</p><ul><li>Within the extension type body using <code>i</code> (or <code>this.i</code> in a constructor).</li><li>Outside with a property extraction using <code>e.i</code> (where <code>e</code> has the extension type as its static type).</li></ul><p>Extension type declarations can also include <a href="generics">type parameters</a> just like classes or extensions:</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">extension type</span><span style="color:#0468D7"> E</span><span style="color:#222222"><</span><span style="color:#0468D7">T</span><span style="color:#222222">>(</span><span style="color:#0468D7">List</span><span style="color:#222222"><</span><span style="color:#0468D7">T</span><span style="color:#222222">> elements) {</span></span> <span class="line"><span style="color:#6E6E70"> // ...</span></span> <span class="line"><span style="color:#222222">}</span></span></code></pre></div></div><div class="header-wrapper"><h3 id="constructors">Constructors</h3><a class="heading-link" href="#constructors" aria-label="Link to 'Constructors' section">#</a></div><p>You can optionally declare <a href="/language/constructors">constructors</a> in an extension type's body. The representation declaration itself is an implicit constructor, so by default takes the place of an unnamed constructor for the extension type. Any additional non-redirecting generative constructors must initialize the representation object's instance variable using <code>this.i</code> in its initializer list or formal parameters.</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">extension type</span><span style="color:#0468D7"> E</span><span style="color:#222222">(</span><span style="color:#0468D7">int</span><span style="color:#222222"> i) {</span></span> <span class="line"><span style="color:#0468D7"> E</span><span style="color:#222222">.</span><span style="color:#6200EE">n</span><span style="color:#222222">(</span><span style="color:#D43324">this</span><span style="color:#222222">.i);</span></span> <span class="line"><span style="color:#0468D7"> E</span><span style="color:#222222">.</span><span style="color:#6200EE">m</span><span style="color:#222222">(</span><span style="color:#0468D7">int</span><span style="color:#222222"> j, </span><span style="color:#0468D7">String</span><span style="color:#222222"> foo) : i = j + foo.length;</span></span> <span class="line"><span style="color:#222222">}</span></span> <span class="line"></span> <span class="line"><span style="color:#D43324">void</span><span style="color:#6200EE"> main</span><span style="color:#222222">() {</span></span> <span class="line"><span style="color:#0468D7"> E</span><span style="color:#222222">(</span><span style="color:#11796D">4</span><span style="color:#222222">); </span><span style="color:#6E6E70">// Implicit unnamed constructor.</span></span> <span class="line"><span style="color:#0468D7"> E</span><span style="color:#222222">.</span><span style="color:#6200EE">n</span><span style="color:#222222">(</span><span style="color:#11796D">3</span><span style="color:#222222">); </span><span style="color:#6E6E70">// Named constructor.</span></span> <span class="line"><span style="color:#0468D7"> E</span><span style="color:#222222">.</span><span style="color:#6200EE">m</span><span style="color:#222222">(</span><span style="color:#11796D">5</span><span style="color:#222222">, </span><span style="color:#11796D">"Hello!"</span><span style="color:#222222">); </span><span style="color:#6E6E70">// Named constructor with additional parameters.</span></span> <span class="line"><span style="color:#222222">}</span></span></code></pre></div></div><p>Or, you can name the representation declaration constructor, in which case there is room for an unnamed constructor in the body:</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">extension type</span><span style="color:#D43324"> const</span><span style="color:#0468D7"> E</span><span style="color:#222222">._(</span><span style="color:#0468D7">int</span><span style="color:#222222"> it) {</span></span> <span class="line"><span style="color:#0468D7"> E</span><span style="color:#222222">(): </span><span style="color:#D43324">this</span><span style="color:#222222">._(</span><span style="color:#11796D">42</span><span style="color:#222222">);</span></span> <span class="line"><span style="color:#0468D7"> E</span><span style="color:#222222">.</span><span style="color:#6200EE">otherName</span><span style="color:#222222">(</span><span style="color:#D43324">this</span><span style="color:#222222">.it);</span></span> <span class="line"><span style="color:#222222">}</span></span> <span class="line"></span> <span class="line"><span style="color:#D43324">void</span><span style="color:#6200EE"> main2</span><span style="color:#222222">() {</span></span> <span class="line"><span style="color:#0468D7"> E</span><span style="color:#222222">();</span></span> <span class="line"><span style="color:#D43324"> const</span><span style="color:#0468D7"> E</span><span style="color:#222222">._(</span><span style="color:#11796D">2</span><span style="color:#222222">);</span></span> <span class="line"><span style="color:#0468D7"> E</span><span style="color:#222222">.</span><span style="color:#6200EE">otherName</span><span style="color:#222222">(</span><span style="color:#11796D">3</span><span style="color:#222222">);</span></span> <span class="line"><span style="color:#222222">}</span></span></code></pre></div></div><p>You can also completely hide the constructor, instead of just defining a new one, using the same private constructor syntax for classes, <code>_</code>. For example, if you only want clients constructing <code>E</code> with a <code>String</code>, even though the underlying type is <code>int</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">extension type</span><span style="color:#0468D7"> E</span><span style="color:#222222">._(</span><span style="color:#0468D7">int</span><span style="color:#222222"> i) {</span></span> <span class="line"><span style="color:#0468D7"> E</span><span style="color:#222222">.</span><span style="color:#6200EE">fromString</span><span style="color:#222222">(</span><span style="color:#0468D7">String</span><span style="color:#222222"> foo) : i = </span><span style="color:#0468D7">int</span><span style="color:#222222">.</span><span style="color:#6200EE">parse</span><span style="color:#222222">(foo);</span></span> <span class="line"><span style="color:#222222">}</span></span></code></pre></div></div><p>You can also declare forwarding generative constructors, or <a href="/language/constructors#factory-constructors">factory constructors</a> (which can also forward to constructors of sub-extension types).</p><div class="header-wrapper"><h3 id="members">Members</h3><a class="heading-link" href="#members" aria-label="Link to 'Members' section">#</a></div><p>Declare members in the body of an extension type to define its interface the same way you would for class members. Extension type members can be methods, getters, setters, or operators (non-<a href="/language/functions#external"><code>external</code></a> <a href="/language/classes#instance-variables">instance variables</a> and <a href="/language/methods#abstract-methods">abstract members</a> are not allowed):</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">extension type</span><span style="color:#0468D7"> NumberE</span><span style="color:#222222">(</span><span style="color:#0468D7">int</span><span style="color:#222222"> value) {</span></span> <span class="line"><span style="color:#6E6E70"> // Operator:</span></span> <span class="line"><span style="color:#0468D7"> NumberE</span><span style="color:#D43324"> operator</span><span style="color:#222222"> +(</span><span style="color:#0468D7">NumberE</span><span style="color:#222222"> other) =></span></span> <span class="line"><span style="color:#0468D7"> NumberE</span><span style="color:#222222">(value + other.value);</span></span> <span class="line"><span style="color:#6E6E70"> // Getter:</span></span> <span class="line"><span style="color:#0468D7"> NumberE</span><span style="color:#D43324"> get</span><span style="color:#222222"> myNum => </span><span style="color:#D43324">this</span><span style="color:#222222">;</span></span> <span class="line"><span style="color:#6E6E70"> // Method:</span></span> <span class="line"><span style="color:#0468D7"> bool</span><span style="color:#6200EE"> isValid</span><span style="color:#222222">() => !value.isNegative;</span></span> <span class="line"><span style="color:#222222">}</span></span></code></pre></div></div><p>Interface members of the representation type are not interface members of the extension type <a href="#transparency">by default</a>. To make a single member of the representation type available on the extension type, you must write a declaration for it in the extension type definition, like the <code>operator +</code> in <code>NumberE</code>. You also can define new members unrelated to the representation type, like the <code>i</code> getter and <code>isValid</code> method.</p><div class="header-wrapper"><h3 id="implements">Implements</h3><a class="heading-link" href="#implements" aria-label="Link to 'Implements' section">#</a></div><p>You can optionally use the <code>implements</code> clause to:</p><ul><li>Introduce a subtype relationship on an extension type, AND</li><li>Add the members of the representation object to the extension type interface.</li></ul><p>The <code>implements</code> clause introduces an <a href="https://github.com/dart-lang/language/blob/main/accepted/2.7/static-extension-methods/feature-specification.md#examples">applicability</a> relationship like the one between an <a href="/language/extension-methods">extension method</a> and its <code>on</code> type. Members that are applicable to the supertype are applicable to the subtype as well, unless the subtype has a declaration with the same member name.</p><p>An extension type can only implement:</p><ul><li><p><strong>Its representation type</strong>. This makes all members of the representation type implicitly available to the extension type.</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">extension type</span><span style="color:#0468D7"> NumberI</span><span style="color:#222222">(</span><span style="color:#0468D7">int</span><span style="color:#222222"> i) </span></span> <span class="line"><span style="color:#D43324"> implements</span><span style="color:#0468D7"> int</span><span style="color:#222222">{</span></span> <span class="line"><span style="color:#6E6E70"> // 'NumberI' can invoke all members of 'int',</span></span> <span class="line"><span style="color:#6E6E70"> // plus anything else it declares here.</span></span> <span class="line"><span style="color:#222222">}</span></span></code></pre></div></div></li><li><p><strong>A supertype of its representation type</strong>. This makes the members of the supertype available, while not necessarily all the members of representation type.</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">extension type</span><span style="color:#0468D7"> Sequence</span><span style="color:#222222"><</span><span style="color:#0468D7">T</span><span style="color:#222222">>(</span><span style="color:#0468D7">List</span><span style="color:#222222"><</span><span style="color:#0468D7">T</span><span style="color:#222222">> _) </span><span style="color:#D43324">implements</span><span style="color:#0468D7"> Iterable</span><span style="color:#222222"><</span><span style="color:#0468D7">T</span><span style="color:#222222">> {</span></span> <span class="line"><span style="color:#6E6E70"> // Better operations than List.</span></span> <span class="line"><span style="color:#222222">}</span></span> <span class="line"></span> <span class="line"><span style="color:#D43324">extension type</span><span style="color:#0468D7"> Id</span><span style="color:#222222">(</span><span style="color:#0468D7">int</span><span style="color:#222222"> _id) </span><span style="color:#D43324">implements</span><span style="color:#0468D7"> Object</span><span style="color:#222222"> {</span></span> <span class="line"><span style="color:#6E6E70"> // Makes the extension type non-nullable.</span></span> <span class="line"><span style="color:#D43324"> static</span><span style="color:#0468D7"> Id</span><span style="color:#222222">? </span><span style="color:#6200EE">tryParse</span><span style="color:#222222">(</span><span style="color:#0468D7">String</span><span style="color:#222222"> source) => </span><span style="color:#0468D7">int</span><span style="color:#222222">.</span><span style="color:#6200EE">tryParse</span><span style="color:#222222">(source) </span><span style="color:#D43324">as</span><span style="color:#0468D7"> Id</span><span style="color:#222222">?;</span></span> <span class="line"><span style="color:#222222">}</span></span></code></pre></div></div></li><li><p><strong>Another extension type</strong> that is valid on the same representation type. This allows you to reuse operations across multiple extension types (similar to multiple inheritance).</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">extension type</span><span style="color:#D43324"> const</span><span style="color:#0468D7"> Opt</span><span style="color:#222222"><</span><span style="color:#0468D7">T</span><span style="color:#222222">>._(({</span><span style="color:#0468D7">T</span><span style="color:#222222"> value})? _) { </span></span> <span class="line"><span style="color:#D43324"> const</span><span style="color:#D43324"> factory</span><span style="color:#0468D7"> Opt</span><span style="color:#222222">(</span><span style="color:#0468D7">T</span><span style="color:#222222"> value) = </span><span style="color:#0468D7">Val</span><span style="color:#222222"><</span><span style="color:#0468D7">T</span><span style="color:#222222">>;</span></span> <span class="line"><span style="color:#D43324"> const</span><span style="color:#D43324"> factory</span><span style="color:#0468D7"> Opt</span><span style="color:#222222">.</span><span style="color:#6200EE">none</span><span style="color:#222222">() = </span><span style="color:#0468D7">Non</span><span style="color:#222222"><</span><span style="color:#0468D7">T</span><span style="color:#222222">>;</span></span> <span class="line"><span style="color:#222222">}</span></span> <span class="line"><span style="color:#D43324">extension type</span><span style="color:#D43324"> const</span><span style="color:#0468D7"> Val</span><span style="color:#222222"><</span><span style="color:#0468D7">T</span><span style="color:#222222">>._(({</span><span style="color:#0468D7">T</span><span style="color:#222222"> value}) _) </span><span style="color:#D43324">implements</span><span style="color:#0468D7"> Opt</span><span style="color:#222222"><</span><span style="color:#0468D7">T</span><span style="color:#222222">> { </span></span> <span class="line"><span style="color:#D43324"> const</span><span style="color:#0468D7"> Val</span><span style="color:#222222">(</span><span style="color:#0468D7">T</span><span style="color:#222222"> value) : </span><span style="color:#D43324">this</span><span style="color:#222222">._((value: value));</span></span> <span class="line"><span style="color:#0468D7"> T</span><span style="color:#D43324"> get</span><span style="color:#222222"> value => _.value;</span></span> <span class="line"><span style="color:#222222">}</span></span> <span class="line"><span style="color:#D43324">extension type</span><span style="color:#D43324"> const</span><span style="color:#0468D7"> Non</span><span style="color:#222222"><</span><span style="color:#0468D7">T</span><span style="color:#222222">>._(</span><span style="color:#0468D7">Null</span><span style="color:#222222"> _) </span><span style="color:#D43324">implements</span><span style="color:#0468D7"> Opt</span><span style="color:#222222"><</span><span style="color:#0468D7">Never</span><span style="color:#222222">> {</span></span> <span class="line"><span style="color:#D43324"> const</span><span style="color:#0468D7"> Non</span><span style="color:#222222">() : </span><span style="color:#D43324">this</span><span style="color:#222222">._(</span><span style="color:#11796D">null</span><span style="color:#222222">);</span></span> <span class="line"><span style="color:#222222">}</span></span></code></pre></div></div></li></ul><p>Read the <a href="#usage">Usage</a> section to learn more about the effect of <code>implements</code> in different scenarios.</p><div class="header-wrapper"><h4 id="redeclare"><code>@redeclare</code></h4><a class="heading-link" href="#redeclare" aria-label="Link to '@redeclare' section">#</a></div><p>Declaring an extension type member that shares a name with a member of a supertype is <em>not</em> an override relationship like it is between classes, but rather a <em>redeclaration</em>. An extension type member declaration <em>completely replaces</em> any supertype member with the same name. It's not possible to provide an alternative implementation for the same function.</p><p>You can use the <code>@redeclare</code> annotation to tell the compiler you are <em>knowingly</em> choosing to use the same name as a supertype's member. The analyzer will then warn you if that's not actually true, for example if one of the names are mistyped.</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">extension type</span><span style="color:#0468D7"> MyString</span><span style="color:#222222">(</span><span style="color:#0468D7">String</span><span style="color:#222222"> _) </span><span style="color:#D43324">implements</span><span style="color:#0468D7"> String</span><span style="color:#222222"> {</span></span> <span class="line"><span style="color:#6E6E70"> // Replaces 'String.operator[]'</span></span> <span class="line"><span style="color:#D43324"> @redeclare</span></span> <span class="line"><span style="color:#0468D7"> int</span><span style="color:#D43324"> operator</span><span style="color:#222222"> [](</span><span style="color:#0468D7">int</span><span style="color:#222222"> index) => </span><span style="color:#6200EE">codeUnitAt</span><span style="color:#222222">(index);</span></span> <span class="line"><span style="color:#222222">}</span></span></code></pre></div></div><p>You can also enable the lint <a href="/tools/linter-rules/annotate_redeclares"><code>annotate_redeclares</code></a> to get a warning if you declare an extension type method that hides a superinterface member and <em>isn't</em> annotated with <code>@redeclare</code>.</p><div class="header-wrapper"><h2 id="usage">Usage</h2><a class="heading-link" href="#usage" aria-label="Link to 'Usage' section">#</a></div><p>To use an extension type, create an instance the same as you would with a class: by calling a constructor:</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">extension type</span><span style="color:#0468D7"> NumberE</span><span style="color:#222222">(</span><span style="color:#0468D7">int</span><span style="color:#222222"> value) {</span></span> <span class="line"><span style="color:#0468D7"> NumberE</span><span style="color:#D43324"> operator</span><span style="color:#222222"> +(</span><span style="color:#0468D7">NumberE</span><span style="color:#222222"> other) =></span></span> <span class="line"><span style="color:#0468D7"> NumberE</span><span style="color:#222222">(value + other.value);</span></span> <span class="line"></span> <span class="line"><span style="color:#0468D7"> NumberE</span><span style="color:#D43324"> get</span><span style="color:#222222"> next => </span><span style="color:#0468D7">NumberE</span><span style="color:#222222">(value + </span><span style="color:#11796D">1</span><span style="color:#222222">);</span></span> <span class="line"><span style="color:#0468D7"> bool</span><span style="color:#6200EE"> isValid</span><span style="color:#222222">() => !value.isNegative;</span></span> <span class="line"><span style="color:#222222">}</span></span> <span class="line"></span> <span class="line"><span style="color:#D43324">void</span><span style="color:#6200EE"> testE</span><span style="color:#222222">() { </span></span> <span class="line"><span style="color:#D43324"> var</span><span style="color:#0468D7"> num</span><span style="color:#222222"> = </span><span style="color:#0468D7">NumberE</span><span style="color:#222222">(</span><span style="color:#11796D">1</span><span style="color:#222222">);</span></span> <span class="line"><span style="color:#222222">}</span></span></code></pre></div></div><p>Then, you can invoke members on the object as you would with a class object.</p><p>There are two equally valid, but substantially different core use cases for extension types:</p><ol><li>Providing an <em>extended</em> interface to an existing type.</li><li>Providing a <em>different</em> interface to an existing type.</li></ol><aside class="alert alert-info"><div class="alert-header"><span class="material-symbols" aria-hidden="true">info</span> <span>Note</span></div><div class="alert-content"><p>In any case, the representation type of an extension type is never its subtype, so a representation type can't be used interchangeably where the extension type is needed.</p></div></aside><p><a id="transparency"></a></p><div class="header-wrapper"><h3 id="1-provide-an-extended-interface-to-an-existing-type">1. Provide an <em>extended</em> interface to an existing type</h3><a class="heading-link" href="#1-provide-an-extended-interface-to-an-existing-type" aria-label="Link to '1. Provide an extended interface to an existing type' section">#</a></div><p>When an extension type <a href="#implements">implements</a> its representation type, you can consider it "transparent", because it allows the extension type to "see" the underlying type.</p><p>A transparent extension type can invoke all members of the representation type (that aren't <a href="#redeclare">redeclared</a>), plus any auxiliary members it defines. This creates a new, <em>extended</em> interface for an existing type. The new interface is available to expressions whose static type is the extension type.</p><p>This means you <em>can</em> invoke members of the representation type (unlike a <a href="#2-provide-a-different-interface-to-an-existing-type">non-transparent</a> extension type), like so:</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">extension type</span><span style="color:#0468D7"> NumberT</span><span style="color:#222222">(</span><span style="color:#0468D7">int</span><span style="color:#222222"> value) </span></span> <span class="line"><span style="color:#D43324"> implements</span><span style="color:#0468D7"> int</span><span style="color:#222222"> {</span></span> <span class="line"><span style="color:#6E6E70"> // Doesn't explicitly declare any members of 'int'.</span></span> <span class="line"><span style="color:#0468D7"> NumberT</span><span style="color:#D43324"> get</span><span style="color:#222222"> i => </span><span style="color:#D43324">this</span><span style="color:#222222">;</span></span> <span class="line"><span style="color:#222222">}</span></span> <span class="line"></span> <span class="line"><span style="color:#D43324">void</span><span style="color:#222222"> main () {</span></span> <span class="line"><span style="color:#6E6E70"> // All OK: Transparency allows invoking `int` members on the extension type:</span></span> <span class="line"><span style="color:#D43324"> var</span><span style="color:#222222"> v1 = </span><span style="color:#0468D7">NumberT</span><span style="color:#222222">(</span><span style="color:#11796D">1</span><span style="color:#222222">); </span><span style="color:#6E6E70">// v1 type: NumberT</span></span> <span class="line"><span style="color:#0468D7"> int</span><span style="color:#222222"> v2 = </span><span style="color:#0468D7">NumberT</span><span style="color:#222222">(</span><span style="color:#11796D">2</span><span style="color:#222222">); </span><span style="color:#6E6E70">// v2 type: int</span></span> <span class="line"><span style="color:#D43324"> var</span><span style="color:#222222"> v3 = v1.i - v1; </span><span style="color:#6E6E70">// v3 type: int</span></span> <span class="line"><span style="color:#D43324"> var</span><span style="color:#222222"> v4 = v2 + v1; </span><span style="color:#6E6E70">// v4 type: int</span></span> <span class="line"><span style="color:#D43324"> var</span><span style="color:#222222"> v5 = </span><span style="color:#11796D">2</span><span style="color:#222222"> + v1; </span><span style="color:#6E6E70">// v5 type: int</span></span> <span class="line"><span style="color:#6E6E70"> // Error: Extension type interface is not available to representation type</span></span> <span class="line"><span style="color:#222222"> v2.i;</span></span> <span class="line"><span style="color:#222222">}</span></span></code></pre></div></div><p>You can also have a "mostly-transparent" extension type that adds new members and adapts others by redeclaring a given member name from the supertype. This would allow you to use stricter types on some parameters of a method, or different default values, for example.</p><p>Another mostly-transparent extension type approach is to implement a type that is a supertype of the representation type. For example, if the representation type is private but its supertype defines the part of the interface that matters for clients.</p><div class="header-wrapper"><h3 id="2-provide-a-different-interface-to-an-existing-type">2. Provide a <em>different</em> interface to an existing type</h3><a class="heading-link" href="#2-provide-a-different-interface-to-an-existing-type" aria-label="Link to '2. Provide a different interface to an existing type' section">#</a></div><p>An extension type that is not <a href="#transparency">transparent</a> (that does not <a href="#implements"><code>implement</code></a> its representation type) is statically treated as a completely new type, distinct from its representation type. You can't assign it to its representation type, and it doesn't expose its representation type's members.</p><p>For example, take the <code>NumberE</code> extension type we declared under <a href="#usage">Usage</a>:</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">void</span><span style="color:#6200EE"> testE</span><span style="color:#222222">() { </span></span> <span class="line"><span style="color:#D43324"> var</span><span style="color:#222222"> num1 = </span><span style="color:#0468D7">NumberE</span><span style="color:#222222">(</span><span style="color:#11796D">1</span><span style="color:#222222">);</span></span> <span class="line"><span style="color:#0468D7"> int</span><span style="color:#222222"> num2 = </span><span style="color:#0468D7">NumberE</span><span style="color:#222222">(</span><span style="color:#11796D">2</span><span style="color:#222222">); </span><span style="color:#6E6E70">// Error: Can't assign 'NumberE' to 'int'.</span></span> <span class="line"><span style="color:#222222"> </span></span> <span class="line"><span style="color:#222222"> num1.</span><span style="color:#6200EE">isValid</span><span style="color:#222222">(); </span><span style="color:#6E6E70">// OK: Extension member invocation.</span></span> <span class="line"><span style="color:#222222"> num1.</span><span style="color:#6200EE">isNegative</span><span style="color:#222222">(); </span><span style="color:#6E6E70">// Error: 'NumberE' does not define 'int' member 'isNegative'.</span></span> <span class="line"><span style="color:#222222"> </span></span> <span class="line"><span style="color:#D43324"> var</span><span style="color:#222222"> sum1 = num1 + num1; </span><span style="color:#6E6E70">// OK: 'NumberE' defines '+'.</span></span> <span class="line"><span style="color:#D43324"> var</span><span style="color:#222222"> diff1 = num1 - num1; </span><span style="color:#6E6E70">// Error: 'NumberE' does not define 'int' member '-'.</span></span> <span class="line"><span style="color:#D43324"> var</span><span style="color:#222222"> diff2 = num1.value - </span><span style="color:#11796D">2</span><span style="color:#222222">; </span><span style="color:#6E6E70">// OK: Can access representation object with reference.</span></span> <span class="line"><span style="color:#D43324"> var</span><span style="color:#222222"> sum2 = num1 + </span><span style="color:#11796D">2</span><span style="color:#222222">; </span><span style="color:#6E6E70">// Error: Can't assign 'int' to parameter type 'NumberE'. </span></span> <span class="line"><span style="color:#222222"> </span></span> <span class="line"><span style="color:#0468D7"> List</span><span style="color:#222222"><</span><span style="color:#0468D7">NumberE</span><span style="color:#222222">> numbers = [</span></span> <span class="line"><span style="color:#0468D7"> NumberE</span><span style="color:#222222">(</span><span style="color:#11796D">1</span><span style="color:#222222">), </span></span> <span class="line"><span style="color:#222222"> num1.next, </span><span style="color:#6E6E70">// OK: 'next' getter returns type 'NumberE'.</span></span> <span class="line"><span style="color:#11796D"> 1</span><span style="color:#222222">, </span><span style="color:#6E6E70">// Error: Can't assign 'int' element to list type 'NumberE'.</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>You can use an extension type this way to <em>replace</em> the interface of an existing type. This allows you to model an interface that is makes sense for the constraints of your new type (like the <code>IdNumber</code> example in the introduction), while also benefitting from the performance and convenience of a simple pre-defined type, like <code>int</code>.</p><p>This use case is as close as you can get to the complete encapsulation of a wrapper class (but is realistically only a <a href="#type-considerations"><em>somewhat</em> protected</a> abstraction).</p><div class="header-wrapper"><h2 id="type-considerations">Type considerations</h2><a class="heading-link" href="#type-considerations" aria-label="Link to 'Type considerations' section">#</a></div><p>Extension types are a compile-time wrapping construct. At run time, there is absolutely no trace of the extension type. Any type query or similar run-time operations work on the representation type.</p><p>This makes extension types an <em>unsafe</em> abstraction, because you can always find out the representation type at run time and access the underlying object.</p><p>Dynamic type tests (<code>e is T</code>), casts (<code>e as T</code>), and other run-time type queries (like <code>switch (e) ...</code> or <code>if (e case ...)</code>) all evaluate to the underlying representation object, and type check against that object's runtime type. That's true when the static type of <code>e</code> is an extension type, and when testing against an extension type (<code>case MyExtensionType(): ...</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">void</span><span style="color:#6200EE"> main</span><span style="color:#222222">() {</span></span> <span class="line"><span style="color:#D43324"> var</span><span style="color:#222222"> n = </span><span style="color:#0468D7">NumberE</span><span style="color:#222222">(</span><span style="color:#11796D">1</span><span style="color:#222222">);</span></span> <span class="line"></span> <span class="line"><span style="color:#6E6E70"> // Run-time type of 'n' is representation type 'int'.</span></span> <span class="line"><span style="color:#D43324"> if</span><span style="color:#222222"> (n is </span><span style="color:#0468D7">int</span><span style="color:#222222">) </span><span style="color:#6200EE">print</span><span style="color:#222222">(n.value); </span><span style="color:#6E6E70">// Prints 1.</span></span> <span class="line"></span> <span class="line"><span style="color:#6E6E70"> // Can use 'int' methods on 'n' at run time.</span></span> <span class="line"><span style="color:#D43324"> if</span><span style="color:#222222"> (n </span><span style="color:#D43324">case</span><span style="color:#0468D7"> int</span><span style="color:#222222"> x) </span><span style="color:#6200EE">print</span><span style="color:#222222">(x.</span><span style="color:#6200EE">toRadixString</span><span style="color:#222222">(</span><span style="color:#11796D">10</span><span style="color:#222222">)); </span><span style="color:#6E6E70">// Prints 1.</span></span> <span class="line"><span style="color:#D43324"> switch</span><span style="color:#222222"> (n) {</span></span> <span class="line"><span style="color:#D43324"> case</span><span style="color:#0468D7"> int</span><span style="color:#222222">(:</span><span style="color:#D43324">var</span><span style="color:#222222"> isEven): </span><span style="color:#6200EE">print</span><span style="color:#222222">(</span><span style="color:#11796D">"</span><span style="color:#11796D">$</span><span style="color:#222222">n</span><span style="color:#11796D"> (</span><span style="color:#11796D">${</span><span style="color:#222222">isEven</span><span style="color:#11796D"> ? </span><span style="color:#11796D">"even"</span><span style="color:#11796D"> : </span><span style="color:#11796D">"odd"</span><span style="color:#11796D">}</span><span style="color:#11796D">)"</span><span style="color:#222222">); </span><span style="color:#6E6E70">// Prints 1 (odd).</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>Similarly, the static type of the matched value is that of the extension type in this example:</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">void</span><span style="color:#6200EE"> main</span><span style="color:#222222">() {</span></span> <span class="line"><span style="color:#0468D7"> int</span><span style="color:#222222"> i = </span><span style="color:#11796D">2</span><span style="color:#222222">;</span></span> <span class="line"><span style="color:#D43324"> if</span><span style="color:#222222"> (i is </span><span style="color:#0468D7">NumberE</span><span style="color:#222222">) </span><span style="color:#6200EE">print</span><span style="color:#222222">(</span><span style="color:#11796D">"It is"</span><span style="color:#222222">); </span><span style="color:#6E6E70">// Prints 'It is'.</span></span> <span class="line"><span style="color:#D43324"> if</span><span style="color:#222222"> (i </span><span style="color:#D43324">case</span><span style="color:#0468D7"> NumberE</span><span style="color:#222222"> v) </span><span style="color:#6200EE">print</span><span style="color:#222222">(</span><span style="color:#11796D">"value: </span><span style="color:#11796D">${</span><span style="color:#222222">v</span><span style="color:#11796D">.</span><span style="color:#222222">value</span><span style="color:#11796D">}</span><span style="color:#11796D">"</span><span style="color:#222222">); </span><span style="color:#6E6E70">// Prints 'value: 2'.</span></span> <span class="line"><span style="color:#D43324"> switch</span><span style="color:#222222"> (i) {</span></span> <span class="line"><span style="color:#D43324"> case</span><span style="color:#0468D7"> NumberE</span><span style="color:#222222">(:</span><span style="color:#D43324">var</span><span style="color:#222222"> value): </span><span style="color:#6200EE">print</span><span style="color:#222222">(</span><span style="color:#11796D">"value: </span><span style="color:#11796D">$</span><span style="color:#222222">value</span><span style="color:#11796D">"</span><span style="color:#222222">); </span><span style="color:#6E6E70">// Prints 'value: 2'.</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>It's important to be aware of this quality when using extension types. Always keep in mind that an extension type exists and matters at compile time, but gets erased <em>during</em> compilation.</p><p>For example, consider an expression <code>e</code> whose static type is the extension type <code>E</code>, and the representation type of <code>E</code> is <code>R</code>. Then, the run-time type of the value of <code>e</code> is a subtype of <code>R</code>. Even the type itself is erased; <code>List<E></code> is exactly the same thing as <code>List<R></code> at run time.</p><p>In other words, a real wrapper class can encapsulate a wrapped object, whereas an extension type is just a compile-time view on the wrapped object. While a real wrapper is safer, the trade-off is extension types give you the option to avoid wrapper objects, which can greatly improve performance in some scenarios.</p><nav id="subnav"><ul><li class="previous"><a href="/language/extension-methods">⟨ Extension methods</a></li><li class="next"><a href="/language/callable-objects">Callable objects ⟩</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 2024-10-22.</span> <a href="https://github.com/dart-lang/site-www/tree/main/src/content/language/extension-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/language/extension-types/&page-source=https://github.com/dart-lang/site-www/tree/main/src/content/language/extension-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>