{"componentChunkName":"component---src-templates-handbook-tsx","path":"/docs/handbook/variable-declarations.html","result":{"data":{"allSitePage":{"nodes":[{"path":"/dev-404-page/"},{"path":"/docs/handbook/advanced-types.html"},{"path":"/docs/handbook/basic-types.html"},{"path":"/docs/handbook/classes.html"},{"path":"/docs/handbook/compiler-options-in-msbuild.html"},{"path":"/docs/handbook/compiler-options.html"},{"path":"/docs/handbook/configuring-watch.html"},{"path":"/docs/handbook/declaration-merging.html"},{"path":"/docs/handbook/decorators.html"},{"path":"/docs/handbook/enums.html"},{"path":"/docs/handbook/functions.html"},{"path":"/docs/handbook/generics.html"},{"path":"/docs/handbook/integrating-with-build-tools.html"},{"path":"/docs/handbook/interfaces.html"},{"path":"/docs/handbook/iterators-and-generators.html"},{"path":"/docs/handbook/jsdoc-supported-types.html"},{"path":"/docs/handbook/jsx.html"},{"path":"/docs/handbook/literal-types.html"},{"path":"/docs/handbook/mixins.html"},{"path":"/docs/handbook/module-resolution.html"},{"path":"/docs/handbook/modules.html"},{"path":"/docs/handbook/namespaces-and-modules.html"},{"path":"/docs/handbook/namespaces.html"},{"path":"/docs/handbook/nightly-builds.html"},{"path":"/docs/handbook/project-references.html"},{"path":"/docs/handbook/symbols.html"},{"path":"/docs/handbook/"},{"path":"/docs/handbook/triple-slash-directives.html"},{"path":"/docs/handbook/type-checking-javascript-files.html"},{"path":"/docs/handbook/type-compatibility.html"},{"path":"/docs/handbook/type-inference.html"},{"path":"/docs/handbook/unions-and-intersections.html"},{"path":"/docs/handbook/utility-types.html"},{"path":"/docs/handbook/variable-declarations.html"},{"path":"/docs/handbook/writing-declaration-files.html"},{"path":"/docs/handbook/declaration-files/by-example.html"},{"path":"/docs/handbook/declaration-files/consumption.html"},{"path":"/docs/handbook/declaration-files/deep-dive.html"},{"path":"/docs/handbook/declaration-files/do-s-and-don-ts.html"},{"path":"/docs/handbook/declaration-files/introduction.html"},{"path":"/docs/handbook/declaration-files/library-structures.html"},{"path":"/docs/handbook/declaration-files/publishing.html"},{"path":"/docs/handbook/declaration-files/templates.html"},{"path":"/docs/handbook/release-notes/typescript-1-1.html"},{"path":"/docs/handbook/release-notes/typescript-1-3.html"},{"path":"/docs/handbook/release-notes/typescript-1-4.html"},{"path":"/docs/handbook/release-notes/typescript-1-5.html"},{"path":"/docs/handbook/release-notes/typescript-1-6.html"},{"path":"/docs/handbook/release-notes/typescript-1-7.html"},{"path":"/docs/handbook/release-notes/typescript-1-8.html"},{"path":"/docs/handbook/release-notes/typescript-2-0.html"},{"path":"/docs/handbook/release-notes/typescript-2-2.html"},{"path":"/docs/handbook/release-notes/typescript-2-1.html"},{"path":"/docs/handbook/release-notes/typescript-2-3.html"},{"path":"/docs/handbook/release-notes/typescript-2-4.html"},{"path":"/docs/handbook/release-notes/typescript-2-5.html"},{"path":"/docs/handbook/release-notes/typescript-2-6.html"},{"path":"/docs/handbook/release-notes/typescript-2-7.html"},{"path":"/docs/handbook/release-notes/typescript-2-8.html"},{"path":"/docs/handbook/release-notes/typescript-2-9.html"},{"path":"/docs/handbook/release-notes/typescript-3-0.html"},{"path":"/docs/handbook/release-notes/typescript-3-1.html"},{"path":"/docs/handbook/release-notes/typescript-3-2.html"},{"path":"/docs/handbook/release-notes/typescript-3-3.html"},{"path":"/docs/handbook/release-notes/typescript-3-4.html"},{"path":"/docs/handbook/release-notes/typescript-3-5.html"},{"path":"/docs/handbook/release-notes/typescript-3-6.html"},{"path":"/docs/handbook/release-notes/typescript-3-7.html"},{"path":"/docs/handbook/release-notes/typescript-3-8.html"},{"path":"/docs/handbook/asp-net-core.html"},{"path":"/docs/handbook/angular.html"},{"path":"/docs/handbook/dom-manipulation.html"},{"path":"/docs/handbook/gulp.html"},{"path":"/docs/handbook/migrating-from-javascript.html"},{"path":"/docs/handbook/react-&-webpack.html"},{"path":"/docs/handbook/react.html"},{"path":"/docs/handbook/typescript-in-5-minutes-func.html"},{"path":"/docs/handbook/typescript-in-5-minutes.html"},{"path":"/docs/handbook/typescript-in-5-minutes-oop.html"},{"path":"/docs/handbook/typescript-from-scratch.html"},{"path":"/docs/handbook/typescript-tooling-in-5-minutes.html"},{"path":"/docs/handbook/tsconfig-json.html"},{"path":"/docs/handbook/declaration-files/templates/global-modifying-module-d-ts.html"},{"path":"/docs/handbook/declaration-files/templates/global-plugin-d-ts.html"},{"path":"/docs/handbook/declaration-files/templates/global-d-ts.html"},{"path":"/docs/handbook/declaration-files/templates/module-class-d-ts.html"},{"path":"/docs/handbook/declaration-files/templates/module-function-d-ts.html"},{"path":"/docs/handbook/declaration-files/templates/module-plugin-d-ts.html"},{"path":"/docs/handbook/declaration-files/templates/module-d-ts.html"},{"path":"/docs/handbook/release-notes/overview.html"},{"path":"/tsconfig"},{"path":"/en/tsconfig"},{"path":"/ja/tsconfig"},{"path":"/vo/tsconfig"},{"path":"/play"},{"path":"/en/play"},{"path":"/es/play"},{"path":"/vo/play"},{"path":"/zh/play"},{"path":"/ja/play"},{"path":"/play/3-7/fixits/big-number-literals.ts"},{"path":"/play/3-7/fixits/const-to-let.ts"},{"path":"/play/3-7/fixits/infer-from-usage-changes.ts"},{"path":"/play/3-7/syntax-and-messaging/flattened-error-reporting.ts"},{"path":"/play/3-7/syntax-and-messaging/nullish-coalescing.ts"},{"path":"/play/3-7/syntax-and-messaging/optional-chaining.ts"},{"path":"/play/3-7/types-and-code-flow/assertion-functions.ts"},{"path":"/play/3-7/types-and-code-flow/recursive-type-references.ts"},{"path":"/play/3-7/types-and-code-flow/uncalled-function-checks.ts"},{"path":"/play/3-8/breaking-changes/checking-unions-with-index-signatures.ts"},{"path":"/play/3-8/jsdoc-improvements/accessibility-modifiers.js"},{"path":"/play/3-8/syntax-and-messaging/export-modules-from.ts"},{"path":"/play/3-8/syntax-and-messaging/private-class-fields.ts"},{"path":"/play/javascript/external-apis/typescript-with-deno.ts"},{"path":"/play/javascript/external-apis/typescript-with-node.js"},{"path":"/play/javascript/external-apis/typescript-with-web.js"},{"path":"/play/javascript/external-apis/typescript-with-webgl.js"},{"path":"/play/javascript/functions-with-javascript/function-chaining.ts"},{"path":"/play/javascript/functions-with-javascript/generic-functions.ts"},{"path":"/play/javascript/functions-with-javascript/typing-functions.ts"},{"path":"/play/javascript/helping-with-javascript/errors.ts"},{"path":"/play/javascript/helping-with-javascript/quick-fixes.ts"},{"path":"/play/javascript/javascript-essentials/code-flow.ts"},{"path":"/play/javascript/javascript-essentials/functions.ts"},{"path":"/play/javascript/javascript-essentials/hello-world.ts"},{"path":"/play/javascript/javascript-essentials/objects-and-arrays.ts"},{"path":"/play/javascript/modern-javascript/async-await.ts"},{"path":"/play/javascript/modern-javascript/immutability.ts"},{"path":"/play/javascript/modern-javascript/import-export.ts"},{"path":"/play/javascript/modern-javascript/jsdoc-support.js"},{"path":"/play/javascript/working-with-classes/classes-101.ts"},{"path":"/play/javascript/working-with-classes/generic-classes.ts"},{"path":"/play/javascript/working-with-classes/mixins.ts"},{"path":"/play/javascript/working-with-classes/this.ts"},{"path":"/play/playground/config/javascript-playgrounds.js"},{"path":"/play/playground/config/new-compiler-defaults.ts"},{"path":"/play/playground/language/automatic-type-acquisition.ts"},{"path":"/play/playground/language/fixits.ts"},{"path":"/play/playground/tooling/mobile-support.ts"},{"path":"/play/playground/tooling/sharable-urls.ts"},{"path":"/play/playground/tooling/typescript-versions.ts"},{"path":"/play/typescript/language/soundness.ts"},{"path":"/play/typescript/language/structural-typing.ts"},{"path":"/play/typescript/language/type-guards.ts"},{"path":"/play/typescript/language/type-widening-and-narrowing.ts"},{"path":"/play/typescript/language-extensions/enums.ts"},{"path":"/play/typescript/language-extensions/nominal-typing.ts"},{"path":"/play/typescript/language-extensions/types-vs-interfaces.ts"},{"path":"/play/typescript/meta-types/conditional-types.ts"},{"path":"/play/typescript/meta-types/discriminate-types.ts"},{"path":"/play/typescript/meta-types/indexed-types.ts"},{"path":"/play/typescript/meta-types/mapped-types.ts"},{"path":"/play/typescript/primitives/any.ts"},{"path":"/play/typescript/primitives/literals.ts"},{"path":"/play/typescript/primitives/union-and-intersection-types.ts"},{"path":"/play/typescript/primitives/unknown-and-never.ts"},{"path":"/play/typescript/type-primitives/built-in-utility-types.ts"},{"path":"/play/typescript/type-primitives/nullable-types.ts"},{"path":"/play/typescript/type-primitives/tuples.ts"},{"path":"/es/play/javascript/external-apis/typescript-with-deno.ts"},{"path":"/es/play/javascript/external-apis/typescript-with-node.js"},{"path":"/es/play/javascript/external-apis/typescript-with-web.js"},{"path":"/es/play/javascript/functions-with-javascript/function-chaining.ts"},{"path":"/es/play/javascript/functions-with-javascript/generic-functions.ts"},{"path":"/es/play/javascript/javascript-essentials/hello-world.ts"},{"path":"/es/play/javascript/javascript-essentials/objects-and-arrays.ts"},{"path":"/es/play/typescript/type-primitives/built-in-utility-types.ts"},{"path":"/es/play/typescript/type-primitives/nullable-types.ts"},{"path":"/es/play/typescript/type-primitives/tuples.ts"},{"path":"/ja/play/typescript/language-extensions/enums.ts"},{"path":"/ja/play/typescript/language-extensions/nominal-typing.ts"},{"path":"/ja/play/typescript/language-extensions/types-vs-interfaces.ts"},{"path":"/ja/play/typescript/primitives/any.ts"},{"path":"/ja/play/typescript/primitives/literals.ts"},{"path":"/ja/play/typescript/primitives/union-and-intersection-types.ts"},{"path":"/ja/play/typescript/type-primitives/built-in-utility-types.ts"},{"path":"/vo/play/javascript/javascript-essentials/code-flow.ts"},{"path":"/vo/play/javascript/javascript-essentials/functions.ts"},{"path":"/vo/play/javascript/javascript-essentials/hello-world.ts"},{"path":"/vo/play/javascript/javascript-essentials/objects-and-arrays.ts"},{"path":"/zh/play/javascript/external-apis/typescript-with-deno.ts"},{"path":"/zh/play/javascript/external-apis/typescript-with-node.js"},{"path":"/zh/play/javascript/external-apis/typescript-with-web.js"},{"path":"/zh/play/javascript/external-apis/typescript-with-webgl.js"},{"path":"/zh/play/javascript/functions-with-javascript/function-chaining.ts"},{"path":"/zh/play/javascript/functions-with-javascript/generic-functions.ts"},{"path":"/zh/play/javascript/functions-with-javascript/typing-functions.ts"},{"path":"/zh/play/javascript/helping-with-javascript/errors.ts"},{"path":"/zh/play/javascript/helping-with-javascript/quick-fixes.ts"},{"path":"/zh/play/javascript/javascript-essentials/code-flow.ts"},{"path":"/zh/play/javascript/javascript-essentials/functions.ts"},{"path":"/zh/play/javascript/javascript-essentials/hello-world.ts"},{"path":"/zh/play/javascript/modern-javascript/import-export.ts"},{"path":"/zh/play/javascript/modern-javascript/jsdoc-support.js"},{"path":"/zh/play/javascript/working-with-classes/classes-101.ts"},{"path":"/zh/play/javascript/working-with-classes/generic-classes.ts"},{"path":"/zh/play/javascript/working-with-classes/mixins.ts"},{"path":"/zh/play/javascript/working-with-classes/this.ts"},{"path":"/zh/play/playground/config/javascript-playgrounds.js"},{"path":"/zh/play/playground/config/new-compiler-defaults.ts"},{"path":"/zh/play/playground/language/automatic-type-acquisition.ts"},{"path":"/zh/play/playground/language/fixits.ts"},{"path":"/zh/play/playground/tooling/mobile-support.ts"},{"path":"/zh/play/playground/tooling/sharable-urls.ts"},{"path":"/zh/play/playground/tooling/typescript-versions.ts"},{"path":"/zh/play/typescript/language/soundness.ts"},{"path":"/zh/play/typescript/language/structural-typing.ts"},{"path":"/zh/play/typescript/language/type-guards.ts"},{"path":"/zh/play/typescript/language/type-widening-and-narrowing.ts"},{"path":"/zh/play/typescript/language-extensions/enums.ts"},{"path":"/zh/play/typescript/language-extensions/nominal-typing.ts"},{"path":"/zh/play/typescript/language-extensions/types-vs-interfaces.ts"},{"path":"/zh/play/typescript/meta-types/conditional-types.ts"},{"path":"/zh/play/typescript/meta-types/discriminate-types.ts"},{"path":"/zh/play/typescript/meta-types/indexed-types.ts"},{"path":"/zh/play/typescript/meta-types/mapped-types.ts"},{"path":"/zh/play/typescript/primitives/any.ts"},{"path":"/zh/play/typescript/primitives/literals.ts"},{"path":"/zh/play/typescript/primitives/union-and-intersection-types.ts"},{"path":"/zh/play/typescript/primitives/unknown-and-never.ts"},{"path":"/zh/play/typescript/type-primitives/built-in-utility-types.ts"},{"path":"/zh/play/typescript/type-primitives/nullable-types.ts"},{"path":"/zh/play/typescript/type-primitives/tuples.ts"},{"path":"/zh/play/javascript/modern-javascript/immutability.ts"},{"path":"/zh/play/javascript/modern-javascript/async-await.ts"},{"path":"/zh/play/javascript/javascript-essentials/objects-and-arrays.ts"},{"path":"/community"},{"path":"/es/community"},{"path":"/ja/community"},{"path":"/vo/community"},{"path":"/zh/community"},{"path":"/download"},{"path":"/es/download"},{"path":"/ja/download"},{"path":"/vo/download"},{"path":"/zh/download"},{"path":"/empty"},{"path":"/es/empty"},{"path":"/ja/empty"},{"path":"/vo/empty"},{"path":"/zh/empty"},{"path":"/"},{"path":"/es/"},{"path":"/ja/"},{"path":"/vo/"},{"path":"/zh/"},{"path":"/tools"},{"path":"/es/tools"},{"path":"/ja/tools"},{"path":"/vo/tools"},{"path":"/zh/tools"},{"path":"/why-create-typescript"},{"path":"/es/why-create-typescript"},{"path":"/ja/why-create-typescript"},{"path":"/vo/why-create-typescript"},{"path":"/zh/why-create-typescript"},{"path":"/docs/home"},{"path":"/es/docs/home"},{"path":"/ja/docs/home"},{"path":"/vo/docs/home"},{"path":"/zh/docs/home"},{"path":"/dev/playground-plugins/"},{"path":"/dev/sandbox/"},{"path":"/dev/twoslash/"},{"path":"/dev/typescript-vfs/"}]},"markdownRemark":{"id":"4b3300d7-6ca9-5e70-b311-40c6a45771e5","excerpt":"Variable Declarations let and const are two relatively new types of variable declarations in JavaScript.\nAs we mentioned earlier, let is similar to var in some…","html":"<h1 id=\"variable-declarations\" style=\"position:relative;\"><a href=\"#variable-declarations\" aria-label=\"variable declarations permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Variable Declarations</h1>\n<p><code>let</code> and <code>const</code> are two relatively new types of variable declarations in JavaScript.\n<a href=\"./Basic%20Types.md#a-note-about-let\">As we mentioned earlier</a>, <code>let</code> is similar to <code>var</code> in some respects, but allows users to avoid some of the common “gotchas” that users run into in JavaScript.\n<code>const</code> is an augmentation of <code>let</code> in that it prevents re-assignment to a variable.</p>\n<p>With TypeScript being an extension of JavaScript, the language naturally supports <code>let</code> and <code>const</code>.\nHere we’ll elaborate more on these new declarations and why they’re preferable to <code>var</code>.</p>\n<p>If you’ve used JavaScript offhandedly, the next section might be a good way to refresh your memory.\nIf you’re intimately familiar with all the quirks of <code>var</code> declarations in JavaScript, you might find it easier to skip ahead.</p>\n<h1 id=\"var-declarations\" style=\"position:relative;\"><a href=\"#var-declarations\" aria-label=\"var declarations permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a><code>var</code> declarations</h1>\n<p>Declaring a variable in JavaScript has always traditionally been done with the <code>var</code> keyword.</p>\n<pre class=\"shiki\"><div class=\"language-id\">ts</div><div class='code-container'><code><span style=\"color: #0000FF\">var</span><span style=\"color: #000000\"> a = </span><span style=\"color: #09835A\">10</span><span style=\"color: #000000\">;</span></code></div></pre>\n<p>As you might’ve figured out, we just declared a variable named <code>a</code> with the value <code>10</code>.</p>\n<p>We can also declare a variable inside of a function:</p>\n<pre class=\"shiki\"><div class=\"language-id\">ts</div><div class='code-container'><code><span style=\"color: #0000FF\">function</span><span style=\"color: #000000\"> f() {</span>\n<span style=\"color: #000000\">  </span><span style=\"color: #0000FF\">var</span><span style=\"color: #000000\"> message = </span><span style=\"color: #A31515\">\"Hello, world!\"</span><span style=\"color: #000000\">;</span>\n\n<span style=\"color: #000000\">  </span><span style=\"color: #0000FF\">return</span><span style=\"color: #000000\"> message;</span>\n<span style=\"color: #000000\">}</span></code></div></pre>\n<p>and we can also access those same variables within other functions:</p>\n<pre class=\"shiki\"><div class=\"language-id\">ts</div><div class='code-container'><code><span style=\"color: #0000FF\">function</span><span style=\"color: #000000\"> f() {</span>\n<span style=\"color: #000000\">  </span><span style=\"color: #0000FF\">var</span><span style=\"color: #000000\"> a = </span><span style=\"color: #09835A\">10</span><span style=\"color: #000000\">;</span>\n<span style=\"color: #000000\">  </span><span style=\"color: #0000FF\">return</span><span style=\"color: #000000\"> </span><span style=\"color: #0000FF\">function</span><span style=\"color: #000000\"> g() {</span>\n<span style=\"color: #000000\">    </span><span style=\"color: #0000FF\">var</span><span style=\"color: #000000\"> b = a + </span><span style=\"color: #09835A\">1</span><span style=\"color: #000000\">;</span>\n<span style=\"color: #000000\">    </span><span style=\"color: #0000FF\">return</span><span style=\"color: #000000\"> b;</span>\n<span style=\"color: #000000\">  };</span>\n<span style=\"color: #000000\">}</span>\n\n<span style=\"color: #0000FF\">var</span><span style=\"color: #000000\"> g = f();</span>\n<span style=\"color: #000000\">g(); </span><span style=\"color: #008000\">// returns '11'</span></code></div></pre>\n<p>In this above example, <code>g</code> captured the variable <code>a</code> declared in <code>f</code>.\nAt any point that <code>g</code> gets called, the value of <code>a</code> will be tied to the value of <code>a</code> in <code>f</code>.\nEven if <code>g</code> is called once <code>f</code> is done running, it will be able to access and modify <code>a</code>.</p>\n<pre class=\"shiki\"><div class=\"language-id\">ts</div><div class='code-container'><code><span style=\"color: #0000FF\">function</span><span style=\"color: #000000\"> f() {</span>\n<span style=\"color: #000000\">  </span><span style=\"color: #0000FF\">var</span><span style=\"color: #000000\"> a = </span><span style=\"color: #09835A\">1</span><span style=\"color: #000000\">;</span>\n\n<span style=\"color: #000000\">  a = </span><span style=\"color: #09835A\">2</span><span style=\"color: #000000\">;</span>\n<span style=\"color: #000000\">  </span><span style=\"color: #0000FF\">var</span><span style=\"color: #000000\"> b = g();</span>\n<span style=\"color: #000000\">  a = </span><span style=\"color: #09835A\">3</span><span style=\"color: #000000\">;</span>\n\n<span style=\"color: #000000\">  </span><span style=\"color: #0000FF\">return</span><span style=\"color: #000000\"> b;</span>\n\n<span style=\"color: #000000\">  </span><span style=\"color: #0000FF\">function</span><span style=\"color: #000000\"> g() {</span>\n<span style=\"color: #000000\">    </span><span style=\"color: #0000FF\">return</span><span style=\"color: #000000\"> a;</span>\n<span style=\"color: #000000\">  }</span>\n<span style=\"color: #000000\">}</span>\n\n<span style=\"color: #000000\">f(); </span><span style=\"color: #008000\">// returns '2'</span></code></div></pre>\n<h2 id=\"scoping-rules\" style=\"position:relative;\"><a href=\"#scoping-rules\" aria-label=\"scoping rules permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Scoping rules</h2>\n<p><code>var</code> declarations have some odd scoping rules for those used to other languages.\nTake the following example:</p>\n<pre class=\"shiki\"><div class=\"language-id\">ts</div><div class='code-container'><code><span style=\"color: #0000FF\">function</span><span style=\"color: #000000\"> f(shouldInitialize: boolean) {</span>\n<span style=\"color: #000000\">  </span><span style=\"color: #0000FF\">if</span><span style=\"color: #000000\"> (shouldInitialize) {</span>\n<span style=\"color: #000000\">    </span><span style=\"color: #0000FF\">var</span><span style=\"color: #000000\"> x = </span><span style=\"color: #09835A\">10</span><span style=\"color: #000000\">;</span>\n<span style=\"color: #000000\">  }</span>\n\n<span style=\"color: #000000\">  </span><span style=\"color: #0000FF\">return</span><span style=\"color: #000000\"> x;</span>\n<span style=\"color: #000000\">}</span>\n\n<span style=\"color: #000000\">f(</span><span style=\"color: #0000FF\">true</span><span style=\"color: #000000\">); </span><span style=\"color: #008000\">// returns '10'</span>\n<span style=\"color: #000000\">f(</span><span style=\"color: #0000FF\">false</span><span style=\"color: #000000\">); </span><span style=\"color: #008000\">// returns 'undefined'</span></code></div></pre>\n<p>Some readers might do a double-take at this example.\nThe variable <code>x</code> was declared <em>within the <code>if</code> block</em>, and yet we were able to access it from outside that block.\nThat’s because <code>var</code> declarations are accessible anywhere within their containing function, module, namespace, or global scope - all which we’ll go over later on - regardless of the containing block.\nSome people call this <em><code>var</code>-scoping</em> or <em>function-scoping</em>.\nParameters are also function scoped.</p>\n<p>These scoping rules can cause several types of mistakes.\nOne problem they exacerbate is the fact that it is not an error to declare the same variable multiple times:</p>\n<pre class=\"shiki\"><div class=\"language-id\">ts</div><div class='code-container'><code><span style=\"color: #0000FF\">function</span><span style=\"color: #000000\"> sumMatrix(matrix: number[][]) {</span>\n<span style=\"color: #000000\">  </span><span style=\"color: #0000FF\">var</span><span style=\"color: #000000\"> sum = </span><span style=\"color: #09835A\">0</span><span style=\"color: #000000\">;</span>\n<span style=\"color: #000000\">  </span><span style=\"color: #0000FF\">for</span><span style=\"color: #000000\"> (</span><span style=\"color: #0000FF\">var</span><span style=\"color: #000000\"> i = </span><span style=\"color: #09835A\">0</span><span style=\"color: #000000\">; i &lt; matrix.length; i++) {</span>\n<span style=\"color: #000000\">    </span><span style=\"color: #0000FF\">var</span><span style=\"color: #000000\"> currentRow = matrix[i];</span>\n<span style=\"color: #000000\">    </span><span style=\"color: #0000FF\">for</span><span style=\"color: #000000\"> (</span><span style=\"color: #0000FF\">var</span><span style=\"color: #000000\"> i = </span><span style=\"color: #09835A\">0</span><span style=\"color: #000000\">; i &lt; currentRow.length; i++) {</span>\n<span style=\"color: #000000\">      sum += currentRow[i];</span>\n<span style=\"color: #000000\">    }</span>\n<span style=\"color: #000000\">  }</span>\n\n<span style=\"color: #000000\">  </span><span style=\"color: #0000FF\">return</span><span style=\"color: #000000\"> sum;</span>\n<span style=\"color: #000000\">}</span></code></div></pre>\n<p>Maybe it was easy to spot out for some experienced JavaScript developers, but the inner <code>for</code>-loop will accidentally overwrite the variable <code>i</code> because <code>i</code> refers to the same function-scoped variable.\nAs experienced developers know by now, similar sorts of bugs slip through code reviews and can be an endless source of frustration.</p>\n<h2 id=\"variable-capturing-quirks\" style=\"position:relative;\"><a href=\"#variable-capturing-quirks\" aria-label=\"variable capturing quirks permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Variable capturing quirks</h2>\n<p>Take a quick second to guess what the output of the following snippet is:</p>\n<pre class=\"shiki\"><div class=\"language-id\">ts</div><div class='code-container'><code><span style=\"color: #0000FF\">for</span><span style=\"color: #000000\"> (</span><span style=\"color: #0000FF\">var</span><span style=\"color: #000000\"> i = </span><span style=\"color: #09835A\">0</span><span style=\"color: #000000\">; i &lt; </span><span style=\"color: #09835A\">10</span><span style=\"color: #000000\">; i++) {</span>\n<span style=\"color: #000000\">  setTimeout(</span><span style=\"color: #0000FF\">function</span><span style=\"color: #000000\">() {</span>\n<span style=\"color: #000000\">    console.log(i);</span>\n<span style=\"color: #000000\">  }, </span><span style=\"color: #09835A\">100</span><span style=\"color: #000000\"> * i);</span>\n<span style=\"color: #000000\">}</span></code></div></pre>\n<p>For those unfamiliar, <code>setTimeout</code> will try to execute a function after a certain number of milliseconds (though waiting for anything else to stop running).</p>\n<p>Ready? Take a look:</p>\n<pre><code class=\"language-text\">10\n10\n10\n10\n10\n10\n10\n10\n10\n10\n</code></pre>\n<p>Many JavaScript developers are intimately familiar with this behavior, but if you’re surprised, you’re certainly not alone.\nMost people expect the output to be</p>\n<pre><code class=\"language-text\">0\n1\n2\n3\n4\n5\n6\n7\n8\n9\n</code></pre>\n<p>Remember what we mentioned earlier about variable capturing?\nEvery function expression we pass to <code>setTimeout</code> actually refers to the same <code>i</code> from the same scope.</p>\n<p>Let’s take a minute to consider what that means.\n<code>setTimeout</code> will run a function after some number of milliseconds, <em>but only</em> after the <code>for</code> loop has stopped executing;\nBy the time the <code>for</code> loop has stopped executing, the value of <code>i</code> is <code>10</code>.\nSo each time the given function gets called, it will print out <code>10</code>!</p>\n<p>A common work around is to use an IIFE - an Immediately Invoked Function Expression - to capture <code>i</code> at each iteration:</p>\n<pre class=\"shiki\"><div class=\"language-id\">ts</div><div class='code-container'><code><span style=\"color: #0000FF\">for</span><span style=\"color: #000000\"> (</span><span style=\"color: #0000FF\">var</span><span style=\"color: #000000\"> i = </span><span style=\"color: #09835A\">0</span><span style=\"color: #000000\">; i &lt; </span><span style=\"color: #09835A\">10</span><span style=\"color: #000000\">; i++) {</span>\n<span style=\"color: #000000\">  </span><span style=\"color: #008000\">// capture the current state of 'i'</span>\n<span style=\"color: #000000\">  </span><span style=\"color: #008000\">// by invoking a function with its current value</span>\n<span style=\"color: #000000\">  (</span><span style=\"color: #0000FF\">function</span><span style=\"color: #000000\">(i) {</span>\n<span style=\"color: #000000\">    setTimeout(</span><span style=\"color: #0000FF\">function</span><span style=\"color: #000000\">() {</span>\n<span style=\"color: #000000\">      console.log(i);</span>\n<span style=\"color: #000000\">    }, </span><span style=\"color: #09835A\">100</span><span style=\"color: #000000\"> * i);</span>\n<span style=\"color: #000000\">  })(i);</span>\n<span style=\"color: #000000\">}</span></code></div></pre>\n<p>This odd-looking pattern is actually pretty common.\nThe <code>i</code> in the parameter list actually shadows the <code>i</code> declared in the <code>for</code> loop, but since we named them the same, we didn’t have to modify the loop body too much.</p>\n<h1 id=\"let-declarations\" style=\"position:relative;\"><a href=\"#let-declarations\" aria-label=\"let declarations permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a><code>let</code> declarations</h1>\n<p>By now you’ve figured out that <code>var</code> has some problems, which is precisely why <code>let</code> statements were introduced.\nApart from the keyword used, <code>let</code> statements are written the same way <code>var</code> statements are.</p>\n<pre class=\"shiki\"><div class=\"language-id\">ts</div><div class='code-container'><code><span style=\"color: #0000FF\">let</span><span style=\"color: #000000\"> hello = </span><span style=\"color: #A31515\">\"Hello!\"</span><span style=\"color: #000000\">;</span></code></div></pre>\n<p>The key difference is not in the syntax, but in the semantics, which we’ll now dive into.</p>\n<h2 id=\"block-scoping\" style=\"position:relative;\"><a href=\"#block-scoping\" aria-label=\"block scoping permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Block-scoping</h2>\n<p>When a variable is declared using <code>let</code>, it uses what some call <em>lexical-scoping</em> or <em>block-scoping</em>.\nUnlike variables declared with <code>var</code> whose scopes leak out to their containing function, block-scoped variables are not visible outside of their nearest containing block or <code>for</code>-loop.</p>\n<pre class=\"shiki\"><div class=\"language-id\">ts</div><div class='code-container'><code><span style=\"color: #0000FF\">function</span><span style=\"color: #000000\"> f(input: boolean) {</span>\n<span style=\"color: #000000\">  </span><span style=\"color: #0000FF\">let</span><span style=\"color: #000000\"> a = </span><span style=\"color: #09835A\">100</span><span style=\"color: #000000\">;</span>\n\n<span style=\"color: #000000\">  </span><span style=\"color: #0000FF\">if</span><span style=\"color: #000000\"> (input) {</span>\n<span style=\"color: #000000\">    </span><span style=\"color: #008000\">// Still okay to reference 'a'</span>\n<span style=\"color: #000000\">    </span><span style=\"color: #0000FF\">let</span><span style=\"color: #000000\"> b = a + </span><span style=\"color: #09835A\">1</span><span style=\"color: #000000\">;</span>\n<span style=\"color: #000000\">    </span><span style=\"color: #0000FF\">return</span><span style=\"color: #000000\"> b;</span>\n<span style=\"color: #000000\">  }</span>\n\n<span style=\"color: #000000\">  </span><span style=\"color: #008000\">// Error: 'b' doesn't exist here</span>\n<span style=\"color: #000000\">  </span><span style=\"color: #0000FF\">return</span><span style=\"color: #000000\"> b;</span>\n<span style=\"color: #000000\">}</span></code></div></pre>\n<p>Here, we have two local variables <code>a</code> and <code>b</code>.\n<code>a</code>’s scope is limited to the body of <code>f</code> while <code>b</code>’s scope is limited to the containing <code>if</code> statement’s block.</p>\n<p>Variables declared in a <code>catch</code> clause also have similar scoping rules.</p>\n<pre class=\"shiki\"><div class=\"language-id\">ts</div><div class='code-container'><code><span style=\"color: #0000FF\">try</span><span style=\"color: #000000\"> {</span>\n<span style=\"color: #000000\">  </span><span style=\"color: #0000FF\">throw</span><span style=\"color: #000000\"> </span><span style=\"color: #A31515\">\"oh no!\"</span><span style=\"color: #000000\">;</span>\n<span style=\"color: #000000\">} </span><span style=\"color: #0000FF\">catch</span><span style=\"color: #000000\"> (e) {</span>\n<span style=\"color: #000000\">  console.log(</span><span style=\"color: #A31515\">\"Oh well.\"</span><span style=\"color: #000000\">);</span>\n<span style=\"color: #000000\">}</span>\n\n<span style=\"color: #008000\">// Error: 'e' doesn't exist here</span>\n<span style=\"color: #000000\">console.log(e);</span></code></div></pre>\n<p>Another property of block-scoped variables is that they can’t be read or written to before they’re actually declared.\nWhile these variables are “present” throughout their scope, all points up until their declaration are part of their <em>temporal dead zone</em>.\nThis is just a sophisticated way of saying you can’t access them before the <code>let</code> statement, and luckily TypeScript will let you know that.</p>\n<pre class=\"shiki\"><div class=\"language-id\">ts</div><div class='code-container'><code><span style=\"color: #000000\">a++; </span><span style=\"color: #008000\">// illegal to use 'a' before it's declared;</span>\n<span style=\"color: #0000FF\">let</span><span style=\"color: #000000\"> a;</span></code></div></pre>\n<p>Something to note is that you can still <em>capture</em> a block-scoped variable before it’s declared.\nThe only catch is that it’s illegal to call that function before the declaration.\nIf targeting ES2015, a modern runtime will throw an error; however, right now TypeScript is permissive and won’t report this as an error.</p>\n<pre class=\"shiki\"><div class=\"language-id\">ts</div><div class='code-container'><code><span style=\"color: #0000FF\">function</span><span style=\"color: #000000\"> foo() {</span>\n<span style=\"color: #000000\">  </span><span style=\"color: #008000\">// okay to capture 'a'</span>\n<span style=\"color: #000000\">  </span><span style=\"color: #0000FF\">return</span><span style=\"color: #000000\"> a;</span>\n<span style=\"color: #000000\">}</span>\n\n<span style=\"color: #008000\">// illegal call 'foo' before 'a' is declared</span>\n<span style=\"color: #008000\">// runtimes should throw an error here</span>\n<span style=\"color: #000000\">foo();</span>\n\n<span style=\"color: #0000FF\">let</span><span style=\"color: #000000\"> a;</span></code></div></pre>\n<p>For more information on temporal dead zones, see relevant content on the <a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/let#Temporal_dead_zone_and_errors_with_let\">Mozilla Developer Network</a>.</p>\n<h2 id=\"re-declarations-and-shadowing\" style=\"position:relative;\"><a href=\"#re-declarations-and-shadowing\" aria-label=\"re declarations and shadowing permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Re-declarations and Shadowing</h2>\n<p>With <code>var</code> declarations, we mentioned that it didn’t matter how many times you declared your variables; you just got one.</p>\n<pre class=\"shiki\"><div class=\"language-id\">ts</div><div class='code-container'><code><span style=\"color: #0000FF\">function</span><span style=\"color: #000000\"> f(x) {</span>\n<span style=\"color: #000000\">  </span><span style=\"color: #0000FF\">var</span><span style=\"color: #000000\"> x;</span>\n<span style=\"color: #000000\">  </span><span style=\"color: #0000FF\">var</span><span style=\"color: #000000\"> x;</span>\n\n<span style=\"color: #000000\">  </span><span style=\"color: #0000FF\">if</span><span style=\"color: #000000\"> (</span><span style=\"color: #0000FF\">true</span><span style=\"color: #000000\">) {</span>\n<span style=\"color: #000000\">    </span><span style=\"color: #0000FF\">var</span><span style=\"color: #000000\"> x;</span>\n<span style=\"color: #000000\">  }</span>\n<span style=\"color: #000000\">}</span></code></div></pre>\n<p>In the above example, all declarations of <code>x</code> actually refer to the <em>same</em> <code>x</code>, and this is perfectly valid.\nThis often ends up being a source of bugs.\nThankfully, <code>let</code> declarations are not as forgiving.</p>\n<pre class=\"shiki\"><div class=\"language-id\">ts</div><div class='code-container'><code><span style=\"color: #0000FF\">let</span><span style=\"color: #000000\"> x = </span><span style=\"color: #09835A\">10</span><span style=\"color: #000000\">;</span>\n<span style=\"color: #0000FF\">let</span><span style=\"color: #000000\"> x = </span><span style=\"color: #09835A\">20</span><span style=\"color: #000000\">; </span><span style=\"color: #008000\">// error: can't re-declare 'x' in the same scope</span></code></div></pre>\n<p>The variables don’t necessarily need to both be block-scoped for TypeScript to tell us that there’s a problem.</p>\n<pre class=\"shiki\"><div class=\"language-id\">ts</div><div class='code-container'><code><span style=\"color: #0000FF\">function</span><span style=\"color: #000000\"> f(x) {</span>\n<span style=\"color: #000000\">  </span><span style=\"color: #0000FF\">let</span><span style=\"color: #000000\"> x = </span><span style=\"color: #09835A\">100</span><span style=\"color: #000000\">; </span><span style=\"color: #008000\">// error: interferes with parameter declaration</span>\n<span style=\"color: #000000\">}</span>\n\n<span style=\"color: #0000FF\">function</span><span style=\"color: #000000\"> g() {</span>\n<span style=\"color: #000000\">  </span><span style=\"color: #0000FF\">let</span><span style=\"color: #000000\"> x = </span><span style=\"color: #09835A\">100</span><span style=\"color: #000000\">;</span>\n<span style=\"color: #000000\">  </span><span style=\"color: #0000FF\">var</span><span style=\"color: #000000\"> x = </span><span style=\"color: #09835A\">100</span><span style=\"color: #000000\">; </span><span style=\"color: #008000\">// error: can't have both declarations of 'x'</span>\n<span style=\"color: #000000\">}</span></code></div></pre>\n<p>That’s not to say that a block-scoped variable can never be declared with a function-scoped variable.\nThe block-scoped variable just needs to be declared within a distinctly different block.</p>\n<pre class=\"shiki\"><div class=\"language-id\">ts</div><div class='code-container'><code><span style=\"color: #0000FF\">function</span><span style=\"color: #000000\"> f(condition, x) {</span>\n<span style=\"color: #000000\">  </span><span style=\"color: #0000FF\">if</span><span style=\"color: #000000\"> (condition) {</span>\n<span style=\"color: #000000\">    </span><span style=\"color: #0000FF\">let</span><span style=\"color: #000000\"> x = </span><span style=\"color: #09835A\">100</span><span style=\"color: #000000\">;</span>\n<span style=\"color: #000000\">    </span><span style=\"color: #0000FF\">return</span><span style=\"color: #000000\"> x;</span>\n<span style=\"color: #000000\">  }</span>\n\n<span style=\"color: #000000\">  </span><span style=\"color: #0000FF\">return</span><span style=\"color: #000000\"> x;</span>\n<span style=\"color: #000000\">}</span>\n\n<span style=\"color: #000000\">f(</span><span style=\"color: #0000FF\">false</span><span style=\"color: #000000\">, </span><span style=\"color: #09835A\">0</span><span style=\"color: #000000\">); </span><span style=\"color: #008000\">// returns '0'</span>\n<span style=\"color: #000000\">f(</span><span style=\"color: #0000FF\">true</span><span style=\"color: #000000\">, </span><span style=\"color: #09835A\">0</span><span style=\"color: #000000\">); </span><span style=\"color: #008000\">// returns '100'</span></code></div></pre>\n<p>The act of introducing a new name in a more nested scope is called <em>shadowing</em>.\nIt is a bit of a double-edged sword in that it can introduce certain bugs on its own in the event of accidental shadowing, while also preventing certain bugs.\nFor instance, imagine we had written our earlier <code>sumMatrix</code> function using <code>let</code> variables.</p>\n<pre class=\"shiki\"><div class=\"language-id\">ts</div><div class='code-container'><code><span style=\"color: #0000FF\">function</span><span style=\"color: #000000\"> sumMatrix(matrix: number[][]) {</span>\n<span style=\"color: #000000\">  </span><span style=\"color: #0000FF\">let</span><span style=\"color: #000000\"> sum = </span><span style=\"color: #09835A\">0</span><span style=\"color: #000000\">;</span>\n<span style=\"color: #000000\">  </span><span style=\"color: #0000FF\">for</span><span style=\"color: #000000\"> (</span><span style=\"color: #0000FF\">let</span><span style=\"color: #000000\"> i = </span><span style=\"color: #09835A\">0</span><span style=\"color: #000000\">; i &lt; matrix.length; i++) {</span>\n<span style=\"color: #000000\">    </span><span style=\"color: #0000FF\">var</span><span style=\"color: #000000\"> currentRow = matrix[i];</span>\n<span style=\"color: #000000\">    </span><span style=\"color: #0000FF\">for</span><span style=\"color: #000000\"> (</span><span style=\"color: #0000FF\">let</span><span style=\"color: #000000\"> i = </span><span style=\"color: #09835A\">0</span><span style=\"color: #000000\">; i &lt; currentRow.length; i++) {</span>\n<span style=\"color: #000000\">      sum += currentRow[i];</span>\n<span style=\"color: #000000\">    }</span>\n<span style=\"color: #000000\">  }</span>\n\n<span style=\"color: #000000\">  </span><span style=\"color: #0000FF\">return</span><span style=\"color: #000000\"> sum;</span>\n<span style=\"color: #000000\">}</span></code></div></pre>\n<p>This version of the loop will actually perform the summation correctly because the inner loop’s <code>i</code> shadows <code>i</code> from the outer loop.</p>\n<p>Shadowing should <em>usually</em> be avoided in the interest of writing clearer code.\nWhile there are some scenarios where it may be fitting to take advantage of it, you should use your best judgement.</p>\n<h2 id=\"block-scoped-variable-capturing\" style=\"position:relative;\"><a href=\"#block-scoped-variable-capturing\" aria-label=\"block scoped variable capturing permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Block-scoped variable capturing</h2>\n<p>When we first touched on the idea of variable capturing with <code>var</code> declaration, we briefly went into how variables act once captured.\nTo give a better intuition of this, each time a scope is run, it creates an “environment” of variables.\nThat environment and its captured variables can exist even after everything within its scope has finished executing.</p>\n<pre class=\"shiki\"><div class=\"language-id\">ts</div><div class='code-container'><code><span style=\"color: #0000FF\">function</span><span style=\"color: #000000\"> theCityThatAlwaysSleeps() {</span>\n<span style=\"color: #000000\">  </span><span style=\"color: #0000FF\">let</span><span style=\"color: #000000\"> getCity;</span>\n\n<span style=\"color: #000000\">  </span><span style=\"color: #0000FF\">if</span><span style=\"color: #000000\"> (</span><span style=\"color: #0000FF\">true</span><span style=\"color: #000000\">) {</span>\n<span style=\"color: #000000\">    </span><span style=\"color: #0000FF\">let</span><span style=\"color: #000000\"> city = </span><span style=\"color: #A31515\">\"Seattle\"</span><span style=\"color: #000000\">;</span>\n<span style=\"color: #000000\">    getCity = </span><span style=\"color: #0000FF\">function</span><span style=\"color: #000000\">() {</span>\n<span style=\"color: #000000\">      </span><span style=\"color: #0000FF\">return</span><span style=\"color: #000000\"> city;</span>\n<span style=\"color: #000000\">    };</span>\n<span style=\"color: #000000\">  }</span>\n\n<span style=\"color: #000000\">  </span><span style=\"color: #0000FF\">return</span><span style=\"color: #000000\"> getCity();</span>\n<span style=\"color: #000000\">}</span></code></div></pre>\n<p>Because we’ve captured <code>city</code> from within its environment, we’re still able to access it despite the fact that the <code>if</code> block finished executing.</p>\n<p>Recall that with our earlier <code>setTimeout</code> example, we ended up needing to use an IIFE to capture the state of a variable for every iteration of the <code>for</code> loop.\nIn effect, what we were doing was creating a new variable environment for our captured variables.\nThat was a bit of a pain, but luckily, you’ll never have to do that again in TypeScript.</p>\n<p><code>let</code> declarations have drastically different behavior when declared as part of a loop.\nRather than just introducing a new environment to the loop itself, these declarations sort of create a new scope <em>per iteration</em>.\nSince this is what we were doing anyway with our IIFE, we can change our old <code>setTimeout</code> example to just use a <code>let</code> declaration.</p>\n<pre class=\"shiki\"><div class=\"language-id\">ts</div><div class='code-container'><code><span style=\"color: #0000FF\">for</span><span style=\"color: #000000\"> (</span><span style=\"color: #0000FF\">let</span><span style=\"color: #000000\"> i = </span><span style=\"color: #09835A\">0</span><span style=\"color: #000000\">; i &lt; </span><span style=\"color: #09835A\">10</span><span style=\"color: #000000\">; i++) {</span>\n<span style=\"color: #000000\">  setTimeout(</span><span style=\"color: #0000FF\">function</span><span style=\"color: #000000\">() {</span>\n<span style=\"color: #000000\">    console.log(i);</span>\n<span style=\"color: #000000\">  }, </span><span style=\"color: #09835A\">100</span><span style=\"color: #000000\"> * i);</span>\n<span style=\"color: #000000\">}</span></code></div></pre>\n<p>and as expected, this will print out</p>\n<pre><code class=\"language-text\">0\n1\n2\n3\n4\n5\n6\n7\n8\n9\n</code></pre>\n<h1 id=\"const-declarations\" style=\"position:relative;\"><a href=\"#const-declarations\" aria-label=\"const declarations permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a><code>const</code> declarations</h1>\n<p><code>const</code> declarations are another way of declaring variables.</p>\n<pre class=\"shiki\"><div class=\"language-id\">ts</div><div class='code-container'><code><span style=\"color: #0000FF\">const</span><span style=\"color: #000000\"> numLivesForCat = </span><span style=\"color: #09835A\">9</span><span style=\"color: #000000\">;</span></code></div></pre>\n<p>They are like <code>let</code> declarations but, as their name implies, their value cannot be changed once they are bound.\nIn other words, they have the same scoping rules as <code>let</code>, but you can’t re-assign to them.</p>\n<p>This should not be confused with the idea that the values they refer to are <em>immutable</em>.</p>\n<pre class=\"shiki\"><div class=\"language-id\">ts</div><div class='code-container'><code><span style=\"color: #0000FF\">const</span><span style=\"color: #000000\"> numLivesForCat = </span><span style=\"color: #09835A\">9</span><span style=\"color: #000000\">;</span>\n<span style=\"color: #0000FF\">const</span><span style=\"color: #000000\"> kitty = {</span>\n<span style=\"color: #000000\">  name: </span><span style=\"color: #A31515\">\"Aurora\"</span><span style=\"color: #000000\">,</span>\n<span style=\"color: #000000\">  numLives: numLivesForCat</span>\n<span style=\"color: #000000\">};</span>\n\n<span style=\"color: #008000\">// Error</span>\n<span style=\"color: #000000\">kitty = {</span>\n<span style=\"color: #000000\">  name: </span><span style=\"color: #A31515\">\"Danielle\"</span><span style=\"color: #000000\">,</span>\n<span style=\"color: #000000\">  numLives: numLivesForCat</span>\n<span style=\"color: #000000\">};</span>\n\n<span style=\"color: #008000\">// all \"okay\"</span>\n<span style=\"color: #000000\">kitty.name = </span><span style=\"color: #A31515\">\"Rory\"</span><span style=\"color: #000000\">;</span>\n<span style=\"color: #000000\">kitty.name = </span><span style=\"color: #A31515\">\"Kitty\"</span><span style=\"color: #000000\">;</span>\n<span style=\"color: #000000\">kitty.name = </span><span style=\"color: #A31515\">\"Cat\"</span><span style=\"color: #000000\">;</span>\n<span style=\"color: #000000\">kitty.numLives--;</span></code></div></pre>\n<p>Unless you take specific measures to avoid it, the internal state of a <code>const</code> variable is still modifiable.\nFortunately, TypeScript allows you to specify that members of an object are <code>readonly</code>.\nThe <a href=\"/ea502637541bdf92f195b3d224c7d118/Interfaces.md\">chapter on Interfaces</a> has the details.</p>\n<h1 id=\"let-vs-const\" style=\"position:relative;\"><a href=\"#let-vs-const\" aria-label=\"let vs const permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a><code>let</code> vs. <code>const</code></h1>\n<p>Given that we have two types of declarations with similar scoping semantics, it’s natural to find ourselves asking which one to use.\nLike most broad questions, the answer is: it depends.</p>\n<p>Applying the <a href=\"https://en.wikipedia.org/wiki/Principle_of_least_privilege\">principle of least privilege</a>, all declarations other than those you plan to modify should use <code>const</code>.\nThe rationale is that if a variable didn’t need to get written to, others working on the same codebase shouldn’t automatically be able to write to the object, and will need to consider whether they really need to reassign to the variable.\nUsing <code>const</code> also makes code more predictable when reasoning about flow of data.</p>\n<p>Use your best judgement, and if applicable, consult the matter with the rest of your team.</p>\n<p>The majority of this handbook uses <code>let</code> declarations.</p>\n<h1 id=\"destructuring\" style=\"position:relative;\"><a href=\"#destructuring\" aria-label=\"destructuring permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Destructuring</h1>\n<p>Another ECMAScript 2015 feature that TypeScript has is destructuring.\nFor a complete reference, see <a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment\">the article on the Mozilla Developer Network</a>.\nIn this section, we’ll give a short overview.</p>\n<h2 id=\"array-destructuring\" style=\"position:relative;\"><a href=\"#array-destructuring\" aria-label=\"array destructuring permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Array destructuring</h2>\n<p>The simplest form of destructuring is array destructuring assignment:</p>\n<pre class=\"shiki\"><div class=\"language-id\">ts</div><div class='code-container'><code><span style=\"color: #0000FF\">let</span><span style=\"color: #000000\"> input = [</span><span style=\"color: #09835A\">1</span><span style=\"color: #000000\">, </span><span style=\"color: #09835A\">2</span><span style=\"color: #000000\">];</span>\n<span style=\"color: #0000FF\">let</span><span style=\"color: #000000\"> [first, second] = input;</span>\n<span style=\"color: #000000\">console.log(first); </span><span style=\"color: #008000\">// outputs 1</span>\n<span style=\"color: #000000\">console.log(second); </span><span style=\"color: #008000\">// outputs 2</span></code></div></pre>\n<p>This creates two new variables named <code>first</code> and <code>second</code>.\nThis is equivalent to using indexing, but is much more convenient:</p>\n<pre class=\"shiki\"><div class=\"language-id\">ts</div><div class='code-container'><code><span style=\"color: #000000\">first = input[</span><span style=\"color: #09835A\">0</span><span style=\"color: #000000\">];</span>\n<span style=\"color: #000000\">second = input[</span><span style=\"color: #09835A\">1</span><span style=\"color: #000000\">];</span></code></div></pre>\n<p>Destructuring works with already-declared variables as well:</p>\n<pre class=\"shiki\"><div class=\"language-id\">ts</div><div class='code-container'><code><span style=\"color: #008000\">// swap variables</span>\n<span style=\"color: #000000\">[first, second] = [second, first];</span></code></div></pre>\n<p>And with parameters to a function:</p>\n<pre class=\"shiki\"><div class=\"language-id\">ts</div><div class='code-container'><code><span style=\"color: #0000FF\">function</span><span style=\"color: #000000\"> f([first, second]: [number, number]) {</span>\n<span style=\"color: #000000\">  console.log(first);</span>\n<span style=\"color: #000000\">  console.log(second);</span>\n<span style=\"color: #000000\">}</span>\n<span style=\"color: #000000\">f([</span><span style=\"color: #09835A\">1</span><span style=\"color: #000000\">, </span><span style=\"color: #09835A\">2</span><span style=\"color: #000000\">]);</span></code></div></pre>\n<p>You can create a variable for the remaining items in a list using the syntax <code>...</code>:</p>\n<pre class=\"shiki\"><div class=\"language-id\">ts</div><div class='code-container'><code><span style=\"color: #0000FF\">let</span><span style=\"color: #000000\"> [first, ...rest] = [</span><span style=\"color: #09835A\">1</span><span style=\"color: #000000\">, </span><span style=\"color: #09835A\">2</span><span style=\"color: #000000\">, </span><span style=\"color: #09835A\">3</span><span style=\"color: #000000\">, </span><span style=\"color: #09835A\">4</span><span style=\"color: #000000\">];</span>\n<span style=\"color: #000000\">console.log(first); </span><span style=\"color: #008000\">// outputs 1</span>\n<span style=\"color: #000000\">console.log(rest); </span><span style=\"color: #008000\">// outputs [ 2, 3, 4 ]</span></code></div></pre>\n<p>Of course, since this is JavaScript, you can just ignore trailing elements you don’t care about:</p>\n<pre class=\"shiki\"><div class=\"language-id\">ts</div><div class='code-container'><code><span style=\"color: #0000FF\">let</span><span style=\"color: #000000\"> [first] = [</span><span style=\"color: #09835A\">1</span><span style=\"color: #000000\">, </span><span style=\"color: #09835A\">2</span><span style=\"color: #000000\">, </span><span style=\"color: #09835A\">3</span><span style=\"color: #000000\">, </span><span style=\"color: #09835A\">4</span><span style=\"color: #000000\">];</span>\n<span style=\"color: #000000\">console.log(first); </span><span style=\"color: #008000\">// outputs 1</span></code></div></pre>\n<p>Or other elements:</p>\n<pre class=\"shiki\"><div class=\"language-id\">ts</div><div class='code-container'><code><span style=\"color: #0000FF\">let</span><span style=\"color: #000000\"> [, second, , fourth] = [</span><span style=\"color: #09835A\">1</span><span style=\"color: #000000\">, </span><span style=\"color: #09835A\">2</span><span style=\"color: #000000\">, </span><span style=\"color: #09835A\">3</span><span style=\"color: #000000\">, </span><span style=\"color: #09835A\">4</span><span style=\"color: #000000\">];</span>\n<span style=\"color: #000000\">console.log(second); </span><span style=\"color: #008000\">// outputs 2</span>\n<span style=\"color: #000000\">console.log(fourth); </span><span style=\"color: #008000\">// outputs 4</span></code></div></pre>\n<h2 id=\"tuple-destructuring\" style=\"position:relative;\"><a href=\"#tuple-destructuring\" aria-label=\"tuple destructuring permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Tuple destructuring</h2>\n<p>Tuples may be destructured like arrays; the destructuring variables get the types of the corresponding tuple elements:</p>\n<pre class=\"shiki\"><div class=\"language-id\">ts</div><div class='code-container'><code><span style=\"color: #0000FF\">let</span><span style=\"color: #000000\"> tuple: [number, string, boolean] = [</span><span style=\"color: #09835A\">7</span><span style=\"color: #000000\">, </span><span style=\"color: #A31515\">\"hello\"</span><span style=\"color: #000000\">, </span><span style=\"color: #0000FF\">true</span><span style=\"color: #000000\">];</span>\n\n<span style=\"color: #0000FF\">let</span><span style=\"color: #000000\"> [a, b, c] = tuple; </span><span style=\"color: #008000\">// a: number, b: string, c: boolean</span></code></div></pre>\n<p>It’s an error to destructure a tuple beyond the range of its elements:</p>\n<pre class=\"shiki\"><div class=\"language-id\">ts</div><div class='code-container'><code><span style=\"color: #0000FF\">let</span><span style=\"color: #000000\"> [a, b, c, d] = tuple; </span><span style=\"color: #008000\">// Error, no element at index 3</span></code></div></pre>\n<p>As with arrays, you can destructure the rest of the tuple with <code>...</code>, to get a shorter tuple:</p>\n<pre class=\"shiki\"><div class=\"language-id\">ts</div><div class='code-container'><code><span style=\"color: #0000FF\">let</span><span style=\"color: #000000\"> [a, ...bc] = tuple; </span><span style=\"color: #008000\">// bc: [string, boolean]</span>\n<span style=\"color: #0000FF\">let</span><span style=\"color: #000000\"> [a, b, c, ...d] = tuple; </span><span style=\"color: #008000\">// d: [], the empty tuple</span></code></div></pre>\n<p>Or ignore trailing elements, or other elements:</p>\n<pre class=\"shiki\"><div class=\"language-id\">ts</div><div class='code-container'><code><span style=\"color: #0000FF\">let</span><span style=\"color: #000000\"> [a] = tuple; </span><span style=\"color: #008000\">// a: number</span>\n<span style=\"color: #0000FF\">let</span><span style=\"color: #000000\"> [, b] = tuple; </span><span style=\"color: #008000\">// b: string</span></code></div></pre>\n<h2 id=\"object-destructuring\" style=\"position:relative;\"><a href=\"#object-destructuring\" aria-label=\"object destructuring permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Object destructuring</h2>\n<p>You can also destructure objects:</p>\n<pre class=\"shiki\"><div class=\"language-id\">ts</div><div class='code-container'><code><span style=\"color: #0000FF\">let</span><span style=\"color: #000000\"> o = {</span>\n<span style=\"color: #000000\">  a: </span><span style=\"color: #A31515\">\"foo\"</span><span style=\"color: #000000\">,</span>\n<span style=\"color: #000000\">  b: </span><span style=\"color: #09835A\">12</span><span style=\"color: #000000\">,</span>\n<span style=\"color: #000000\">  c: </span><span style=\"color: #A31515\">\"bar\"</span>\n<span style=\"color: #000000\">};</span>\n<span style=\"color: #0000FF\">let</span><span style=\"color: #000000\"> { a, b } = o;</span></code></div></pre>\n<p>This creates new variables <code>a</code> and <code>b</code> from <code>o.a</code> and <code>o.b</code>.\nNotice that you can skip <code>c</code> if you don’t need it.</p>\n<p>Like array destructuring, you can have assignment without declaration:</p>\n<pre class=\"shiki\"><div class=\"language-id\">ts</div><div class='code-container'><code><span style=\"color: #000000\">({ a, b } = { a: </span><span style=\"color: #A31515\">\"baz\"</span><span style=\"color: #000000\">, b: </span><span style=\"color: #09835A\">101</span><span style=\"color: #000000\"> });</span></code></div></pre>\n<p>Notice that we had to surround this statement with parentheses.\nJavaScript normally parses a <code>{</code> as the start of block.</p>\n<p>You can create a variable for the remaining items in an object using the syntax <code>...</code>:</p>\n<pre class=\"shiki\"><div class=\"language-id\">ts</div><div class='code-container'><code><span style=\"color: #0000FF\">let</span><span style=\"color: #000000\"> { a, ...passthrough } = o;</span>\n<span style=\"color: #0000FF\">let</span><span style=\"color: #000000\"> total = passthrough.b + passthrough.c.length;</span></code></div></pre>\n<h3 id=\"property-renaming\" style=\"position:relative;\"><a href=\"#property-renaming\" aria-label=\"property renaming permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Property renaming</h3>\n<p>You can also give different names to properties:</p>\n<pre class=\"shiki\"><div class=\"language-id\">ts</div><div class='code-container'><code><span style=\"color: #0000FF\">let</span><span style=\"color: #000000\"> { a: newName1, b: newName2 } = o;</span></code></div></pre>\n<p>Here the syntax starts to get confusing.\nYou can read <code>a: newName1</code> as ”<code>a</code> as <code>newName1</code>”.\nThe direction is left-to-right, as if you had written:</p>\n<pre class=\"shiki\"><div class=\"language-id\">ts</div><div class='code-container'><code><span style=\"color: #0000FF\">let</span><span style=\"color: #000000\"> newName1 = o.a;</span>\n<span style=\"color: #0000FF\">let</span><span style=\"color: #000000\"> newName2 = o.b;</span></code></div></pre>\n<p>Confusingly, the colon here does <em>not</em> indicate the type.\nThe type, if you specify it, still needs to be written after the entire destructuring:</p>\n<pre class=\"shiki\"><div class=\"language-id\">ts</div><div class='code-container'><code><span style=\"color: #0000FF\">let</span><span style=\"color: #000000\"> { a, b }: { a: string; b: number } = o;</span></code></div></pre>\n<h3 id=\"default-values\" style=\"position:relative;\"><a href=\"#default-values\" aria-label=\"default values permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Default values</h3>\n<p>Default values let you specify a default value in case a property is undefined:</p>\n<pre class=\"shiki\"><div class=\"language-id\">ts</div><div class='code-container'><code><span style=\"color: #0000FF\">function</span><span style=\"color: #000000\"> keepWholeObject(wholeObject: { a: string; b?: number }) {</span>\n<span style=\"color: #000000\">  </span><span style=\"color: #0000FF\">let</span><span style=\"color: #000000\"> { a, b = </span><span style=\"color: #09835A\">1001</span><span style=\"color: #000000\"> } = wholeObject;</span>\n<span style=\"color: #000000\">}</span></code></div></pre>\n<p>In this example the <code>b?</code> indicates that <code>b</code> is optional, so it may be <code>undefined</code>.\n<code>keepWholeObject</code> now has a variable for <code>wholeObject</code> as well as the properties <code>a</code> and <code>b</code>, even if <code>b</code> is undefined.</p>\n<h2 id=\"function-declarations\" style=\"position:relative;\"><a href=\"#function-declarations\" aria-label=\"function declarations permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Function declarations</h2>\n<p>Destructuring also works in function declarations.\nFor simple cases this is straightforward:</p>\n<pre class=\"shiki\"><div class=\"language-id\">ts</div><div class='code-container'><code><span style=\"color: #0000FF\">type</span><span style=\"color: #000000\"> C = { a: string; b?: number };</span>\n<span style=\"color: #0000FF\">function</span><span style=\"color: #000000\"> f({ a, b }: C): void {</span>\n<span style=\"color: #000000\">  </span><span style=\"color: #008000\">// ...</span>\n<span style=\"color: #000000\">}</span></code></div></pre>\n<p>But specifying defaults is more common for parameters, and getting defaults right with destructuring can be tricky.\nFirst of all, you need to remember to put the pattern before the default value.</p>\n<pre class=\"shiki\"><div class=\"language-id\">ts</div><div class='code-container'><code><span style=\"color: #0000FF\">function</span><span style=\"color: #000000\"> f({ a = </span><span style=\"color: #A31515\">\"\"</span><span style=\"color: #000000\">, b = </span><span style=\"color: #09835A\">0</span><span style=\"color: #000000\"> } = {}): void {</span>\n<span style=\"color: #000000\">  </span><span style=\"color: #008000\">// ...</span>\n<span style=\"color: #000000\">}</span>\n<span style=\"color: #000000\">f();</span></code></div></pre>\n<blockquote>\n<p>The snippet above is an example of type inference, explained later in the handbook.</p>\n</blockquote>\n<p>Then, you need to remember to give a default for optional properties on the destructured property instead of the main initializer.\nRemember that <code>C</code> was defined with <code>b</code> optional:</p>\n<pre class=\"shiki\"><div class=\"language-id\">ts</div><div class='code-container'><code><span style=\"color: #0000FF\">function</span><span style=\"color: #000000\"> f({ a, b = </span><span style=\"color: #09835A\">0</span><span style=\"color: #000000\"> } = { a: </span><span style=\"color: #A31515\">\"\"</span><span style=\"color: #000000\"> }): void {</span>\n<span style=\"color: #000000\">  </span><span style=\"color: #008000\">// ...</span>\n<span style=\"color: #000000\">}</span>\n<span style=\"color: #000000\">f({ a: </span><span style=\"color: #A31515\">\"yes\"</span><span style=\"color: #000000\"> }); </span><span style=\"color: #008000\">// ok, default b = 0</span>\n<span style=\"color: #000000\">f(); </span><span style=\"color: #008000\">// ok, default to { a: \"\" }, which then defaults b = 0</span>\n<span style=\"color: #000000\">f({}); </span><span style=\"color: #008000\">// error, 'a' is required if you supply an argument</span></code></div></pre>\n<p>Use destructuring with care.\nAs the previous example demonstrates, anything but the simplest destructuring expression is confusing.\nThis is especially true with deeply nested destructuring, which gets <em>really</em> hard to understand even without piling on renaming, default values, and type annotations.\nTry to keep destructuring expressions small and simple.\nYou can always write the assignments that destructuring would generate yourself.</p>\n<h2 id=\"spread\" style=\"position:relative;\"><a href=\"#spread\" aria-label=\"spread permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Spread</h2>\n<p>The spread operator is the opposite of destructuring.\nIt allows you to spread an array into another array, or an object into another object.\nFor example:</p>\n<pre class=\"shiki\"><div class=\"language-id\">ts</div><div class='code-container'><code><span style=\"color: #0000FF\">let</span><span style=\"color: #000000\"> first = [</span><span style=\"color: #09835A\">1</span><span style=\"color: #000000\">, </span><span style=\"color: #09835A\">2</span><span style=\"color: #000000\">];</span>\n<span style=\"color: #0000FF\">let</span><span style=\"color: #000000\"> second = [</span><span style=\"color: #09835A\">3</span><span style=\"color: #000000\">, </span><span style=\"color: #09835A\">4</span><span style=\"color: #000000\">];</span>\n<span style=\"color: #0000FF\">let</span><span style=\"color: #000000\"> bothPlus = [</span><span style=\"color: #09835A\">0</span><span style=\"color: #000000\">, ...first, ...second, </span><span style=\"color: #09835A\">5</span><span style=\"color: #000000\">];</span></code></div></pre>\n<p>This gives bothPlus the value <code>[0, 1, 2, 3, 4, 5]</code>.\nSpreading creates a shallow copy of <code>first</code> and <code>second</code>.\nThey are not changed by the spread.</p>\n<p>You can also spread objects:</p>\n<pre class=\"shiki\"><div class=\"language-id\">ts</div><div class='code-container'><code><span style=\"color: #0000FF\">let</span><span style=\"color: #000000\"> defaults = { food: </span><span style=\"color: #A31515\">\"spicy\"</span><span style=\"color: #000000\">, price: </span><span style=\"color: #A31515\">\"$$\"</span><span style=\"color: #000000\">, ambiance: </span><span style=\"color: #A31515\">\"noisy\"</span><span style=\"color: #000000\"> };</span>\n<span style=\"color: #0000FF\">let</span><span style=\"color: #000000\"> search = { ...defaults, food: </span><span style=\"color: #A31515\">\"rich\"</span><span style=\"color: #000000\"> };</span></code></div></pre>\n<p>Now <code>search</code> is <code>{ food: \"rich\", price: \"$$\", ambiance: \"noisy\" }</code>.\nObject spreading is more complex than array spreading.\nLike array spreading, it proceeds from left-to-right, but the result is still an object.\nThis means that properties that come later in the spread object overwrite properties that come earlier.\nSo if we modify the previous example to spread at the end:</p>\n<pre class=\"shiki\"><div class=\"language-id\">ts</div><div class='code-container'><code><span style=\"color: #0000FF\">let</span><span style=\"color: #000000\"> defaults = { food: </span><span style=\"color: #A31515\">\"spicy\"</span><span style=\"color: #000000\">, price: </span><span style=\"color: #A31515\">\"$$\"</span><span style=\"color: #000000\">, ambiance: </span><span style=\"color: #A31515\">\"noisy\"</span><span style=\"color: #000000\"> };</span>\n<span style=\"color: #0000FF\">let</span><span style=\"color: #000000\"> search = { food: </span><span style=\"color: #A31515\">\"rich\"</span><span style=\"color: #000000\">, ...defaults };</span></code></div></pre>\n<p>Then the <code>food</code> property in <code>defaults</code> overwrites <code>food: \"rich\"</code>, which is not what we want in this case.</p>\n<p>Object spread also has a couple of other surprising limits.\nFirst, it only includes an objects’\n<a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Enumerability_and_ownership_of_properties\">own, enumerable properties</a>.\nBasically, that means you lose methods when you spread instances of an object:</p>\n<pre class=\"shiki\"><div class=\"language-id\">ts</div><div class='code-container'><code><span style=\"color: #0000FF\">class</span><span style=\"color: #000000\"> C {</span>\n<span style=\"color: #000000\">  p = </span><span style=\"color: #09835A\">12</span><span style=\"color: #000000\">;</span>\n<span style=\"color: #000000\">  m() {}</span>\n<span style=\"color: #000000\">}</span>\n<span style=\"color: #0000FF\">let</span><span style=\"color: #000000\"> c = </span><span style=\"color: #0000FF\">new</span><span style=\"color: #000000\"> C();</span>\n<span style=\"color: #0000FF\">let</span><span style=\"color: #000000\"> clone = { ...c };</span>\n<span style=\"color: #000000\">clone.p; </span><span style=\"color: #008000\">// ok</span>\n<span style=\"color: #000000\">clone.m(); </span><span style=\"color: #008000\">// error!</span></code></div></pre>\n<p>Second, the TypeScript compiler doesn’t allow spreads of type parameters from generic functions.\nThat feature is expected in future versions of the language.</p>","headings":[{"value":"Variable Declarations","depth":1},{"value":"var declarations","depth":1},{"value":"Scoping rules","depth":2},{"value":"Variable capturing quirks","depth":2},{"value":"let declarations","depth":1},{"value":"Block-scoping","depth":2},{"value":"Re-declarations and Shadowing","depth":2},{"value":"Block-scoped variable capturing","depth":2},{"value":"const declarations","depth":1},{"value":"let vs. const","depth":1},{"value":"Destructuring","depth":1},{"value":"Array destructuring","depth":2},{"value":"Tuple destructuring","depth":2},{"value":"Object destructuring","depth":2},{"value":"Property renaming","depth":3},{"value":"Default values","depth":3},{"value":"Function declarations","depth":2},{"value":"Spread","depth":2}],"frontmatter":{"permalink":"/docs/handbook/variable-declarations.html","title":"Variable Declaration"}}},"pageContext":{"slug":"/docs/handbook/variable-declarations.html","isOldHandbook":true}}}