<p dir="auto"><a href="https://deno.land/manual@v1.32.0/advanced/typescript/configuration#how-deno-uses-a-configuration-file" rel="nofollow">According to the manual</a> — by default — the compiler option <a href="https://www.typescriptlang.org/tsconfig#strict" rel="nofollow"><code class="notranslate">strict</code></a> is <a href="https://deno.land/manual@v1.32.0/advanced/typescript/configuration#how-deno-uses-a-configuration-file:~:text=strict,-true" rel="nofollow">set to <code class="notranslate">true</code></a>, and the option <a href="https://www.typescriptlang.org/tsconfig#useUnknownInCatchVariables" rel="nofollow"><code class="notranslate">useUnknownInCatchVariables</code></a> is currently <a href="https://deno.land/manual@v1.32.0/advanced/typescript/configuration#how-deno-uses-a-configuration-file:~:text=useUnknownInCatchVariables,-false" rel="nofollow">set to <code class="notranslate">false</code></a>.</p>
<p dir="auto">That manual page also shows an example of <a href="https://deno.land/manual@v1.32.0/advanced/typescript/configuration#what-an-implied-tsconfigjson-looks-like" rel="nofollow">what an implied <code class="notranslate">tsconfig.json</code> looks like</a> — which doesn't currently depict the state of this relationship, but that's not the focus of this issue...</p>
<p dir="auto">The TSConfig reference includes this documentation:</p>
<blockquote>
<h2 dir="auto"><a href="https://www.typescriptlang.org/tsconfig#useUnknownInCatchVariables" rel="nofollow"><code class="notranslate">useUnknownInCatchVariables</code></a></h2>
<p dir="auto">In TypeScript 4.0, support was added to allow changing the type of the variable in a catch clause from <code class="notranslate">any</code> to <code class="notranslate">unknown</code>. Allowing for code like:</p>
<div class="highlight highlight-source-ts notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="try {
  // ...
} catch (err) {
  // We have to verify err is an
  // error before using it as one.
  if (err instanceof Error) {
    console.log(err.message);
  }
}"><pre class="notranslate"><span class="pl-k">try</span> <span class="pl-kos">{</span>
  <span class="pl-c">// ...</span>
<span class="pl-kos">}</span> <span class="pl-k">catch</span> <span class="pl-kos">(</span><span class="pl-s1">err</span><span class="pl-kos">)</span> <span class="pl-kos">{</span>
  <span class="pl-c">// We have to verify err is an</span>
  <span class="pl-c">// error before using it as one.</span>
  <span class="pl-k">if</span> <span class="pl-kos">(</span><span class="pl-s1">err</span> <span class="pl-k">instanceof</span> <span class="pl-smi">Error</span><span class="pl-kos">)</span> <span class="pl-kos">{</span>
    <span class="pl-smi">console</span><span class="pl-kos">.</span><span class="pl-en">log</span><span class="pl-kos">(</span><span class="pl-s1">err</span><span class="pl-kos">.</span><span class="pl-c1">message</span><span class="pl-kos">)</span><span class="pl-kos">;</span>
  <span class="pl-kos">}</span>
<span class="pl-kos">}</span></pre></div>
<p dir="auto">This pattern ensures that error handling code becomes more comprehensive because you cannot guarantee that the object being thrown is a Error subclass ahead of time. With the flag <code class="notranslate">useUnknownInCatchVariables</code> enabled, then you do not need the additional syntax (<code class="notranslate">: unknown</code>) nor a linter rule to try enforce this behavior.</p>
<hr>
<p dir="auto"><strong>Default:</strong><br>
<code class="notranslate">true</code> if <a href="https://www.typescriptlang.org/tsconfig#strict" rel="nofollow"><code class="notranslate">strict</code></a>, <code class="notranslate">false</code> otherwise.</p>
<p dir="auto">Related:<br>
<a href="https://www.typescriptlang.org/tsconfig#strict" rel="nofollow"><code class="notranslate">strict</code></a></p>
<p dir="auto">Released:<br>
<a href="https://www.typescriptlang.org/docs/handbook/release-notes/typescript-4-4.html" rel="nofollow">4.4</a></p>
</blockquote>
<p dir="auto">Here are two links to the TS playground comparing the two behaviors (based on the code above):</p>
<ul dir="auto">
<li><a href="https://www.typescriptlang.org/play?useUnknownInCatchVariables=true#code/C4JwngBA3gUBEGMD2A7AzsCSBGArCAvNHPBAOYCmmAthWmgIaUAUAlMaacABYhIDuEFBUEBREHxDMARADkkmHhQgUJSEBDBIArgHIQygDZIkAawCWKMhABm66awDcJeAF8ANCVfP4PPoJxcZ1dEBmAEbghmBAZtNAp2WE5SAHoUgD0AfhgSNIgAdWVuBgA3ZWAkCDKQcxtIGLjlczQIBhQVNQ1sCjsDCDjLa3NMBhbUCgA6ElqohviISww2hAokGwhxSUSXRFQ0JENJ4zJo2PiJ2nomBJ8IEIpDeaTSZHQDo6QTuQUING0+-jFTD8ZQNMjcTBgKgALgct3gr32hwmx1OjQudEYlCcEDyABUAMqhcLcOgQHjNCDUZrABimCheGCuGBAA" rel="nofollow">enabled (<code class="notranslate">true</code>)</a></li>
<li><a href="https://www.typescriptlang.org/play?useUnknownInCatchVariables=false#code/C4JwngBA3gUBEGMD2A7AzsCSBGArCAvNHPBAOYCmmAthWmgIaUAUAlMaacABYhIDuEFBUEBREHxDMARADkkmHhQgUJSEBDBIArgHIQygDZIkAawCWKMhABm66awDcJeAF8ANCVfP4PPoJxcZ1dEBmAEbghmBAZtNAp2WE5SAHoUgD0AfhgSNIgAdWVuBgA3ZWAkCDKQcxtIGLjlczQIBhQVNQ1sCjsDCDjLa3NMBhbUCgA6ElqohviISww2hAokGwhxSUSXRFQ0JENJ4zJo2PiJ2nomBJ8IEIpDeaTSZHQDo6QTuQUING0+-jFTD8ZQNMjcTBgKgALgct3gr32hwmx1OjQudEYlCcEDyABUAMoQAAmSDoKF0mBi4UiPGaEGozWADFMFGhAAK2gpuKoVAAPFYAB2A5lQCxafgE7R5BgAhF4YK4YEA" rel="nofollow">disabled (<code class="notranslate">false</code>)</a></li>
</ul>
<p dir="auto">As the documentation describes: this feature is enabled by default when <code class="notranslate">strict</code> is enabled, but <strong>that's not currently the case in Deno</strong> — and, as the code in the playground links demonstrate, this feature is useful in providing better type safety in <code class="notranslate">catch</code> blocks — helping prevent further potential exceptions.</p>
<p dir="auto">I would like to see Deno set this compiler option to <code class="notranslate">true</code> by default, just like vanilla TS does — and have better type safety in <code class="notranslate">catch</code> blocks.</p>
<p dir="auto">In TypeScript 4.4, the option <code class="notranslate">"useUnknownInCatchVariables"</code> was introduced and was default enabled under <code class="notranslate">"strict"</code> which is the default for Deno.  It is a good change, as it helps ensure code properly guards against non-errors being thrown, which if not properly guarded can cause their own runtime errors.  The problem is that there is <em>a lot</em> of unsafe code out there, which isn't validating that the value is actually an instance of <code class="notranslate">Error</code> including quite a lot in <code class="notranslate">std</code>, so for 1.14 we are doing to disable it, and then enable it for 1.15 to minimise the impact on code.</p>
<p dir="auto">A reminder about our position on breaking changes in TypeScript: <a href="https://deno.land/manual@v1.13.2/typescript/faqs#there-was-a-breaking-change-in-the-version-of-typescript-that-deno-uses-why-did-you-break-my-program" rel="nofollow">https://deno.land/manual@v1.13.2/typescript/faqs#there-was-a-breaking-change-in-the-version-of-typescript-that-deno-uses-why-did-you-break-my-program</a></p>
<p dir="auto">More on the change in TypeScript: <a href="https://devblogs.microsoft.com/typescript/announcing-typescript-4-4-rc/#use-unknown-catch-variables" rel="nofollow">https://devblogs.microsoft.com/typescript/announcing-typescript-4-4-rc/#use-unknown-catch-variables</a></p>
<p dir="auto">Ref <a class="issue-link js-issue-link" data-error-text="Failed to load title" data-id="969770199" data-permission-text="Title is private" data-url="https://github.com/denoland/deno/issues/11678" data-hovercard-type="pull_request" data-hovercard-url="/denoland/deno/pull/11678/hovercard" href="https://github.com/denoland/deno/pull/11678">#11678</a></p>