Skip to content

Commit

Permalink
Hidden side of type predicates post
Browse files Browse the repository at this point in the history
  • Loading branch information
danvk committed Feb 27, 2024
1 parent 07ad6e3 commit 36a8a84
Show file tree
Hide file tree
Showing 11 changed files with 811 additions and 147 deletions.
261 changes: 261 additions & 0 deletions 2024/02/27/type-guards/index.html

Large diffs are not rendered by default.

9 changes: 9 additions & 0 deletions all-posts/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,15 @@ <h4>2024</h4>
</div>
</div>

<div class="row all-posts-post">
<div class="col-sm-2">
2024-02-27
</div>
<div class="col-sm-10">
<a href="/2024/02/27/type-guards/">The Hidden Side of Type Predicates</a>
</div>
</div>

<div class="row all-posts-post">
<div class="col-sm-2">
2024-01-31
Expand Down
339 changes: 339 additions & 0 deletions archives/2024/02/index.html

Large diffs are not rendered by default.

23 changes: 23 additions & 0 deletions archives/2024/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,29 @@ <h2>Recent Blog Posts</h2>

<div class="container">

<div class="row hentry" id="type-guards">
<div class="col-md-12">
<h3 class="entry-title">
<a href="/2024/02/27/type-guards/">The Hidden Side of Type Predicates</a>
</h3>

<div class="text-muted published-container">
<time class="published" datetime="2024-02-27T15:45:00.000Z" itemprop="datePublished">
Tue 27 February 2024
</time>
</div>

<div class="entry-content">

Type guards are a powerful tool for improving TypeScript's built-in control flow analysis. This post looks at when it's appropriate to use a type predicate, and in particular what it means when a type predicate returns <code>false</code>.

<a class="read-more" href="/2024/02/27/type-guards/">Continue&nbsp;reading&nbsp;&raquo;</a>

</div>
</div>
</div>


<div class="row hentry" id="etsy">
<div class="col-md-12">
<h3 class="entry-title">
Expand Down
47 changes: 23 additions & 24 deletions archives/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,29 @@ <h2>Recent Blog Posts</h2>

<div class="container">

<div class="row hentry" id="type-guards">
<div class="col-md-12">
<h3 class="entry-title">
<a href="/2024/02/27/type-guards/">The Hidden Side of Type Predicates</a>
</h3>

<div class="text-muted published-container">
<time class="published" datetime="2024-02-27T15:45:00.000Z" itemprop="datePublished">
Tue 27 February 2024
</time>
</div>

<div class="entry-content">

Type guards are a powerful tool for improving TypeScript's built-in control flow analysis. This post looks at when it's appropriate to use a type predicate, and in particular what it means when a type predicate returns <code>false</code>.

<a class="read-more" href="/2024/02/27/type-guards/">Continue&nbsp;reading&nbsp;&raquo;</a>

</div>
</div>
</div>


<div class="row hentry" id="etsy">
<div class="col-md-12">
<h3 class="entry-title">
Expand Down Expand Up @@ -345,30 +368,6 @@ <h3 class="entry-title">
</div>


<div class="row hentry" id="aoc2022">
<div class="col-md-12">
<h3 class="entry-title">
<a href="/2023/04/27/aoc2022/">A first look at Deno through the Advent of Code 2022</a>
</h3>

<div class="text-muted published-container">
<time class="published" datetime="2023-04-27T21:00:00.000Z" itemprop="datePublished">
Thu 27 April 2023
</time>
</div>

<div class="entry-content">

<p><img src="https://effectivetypescript.com/images/advent-of-code.png" title="Advent of Code Logo" width="64" height="64" style="float: right; margin-left: 10px;">Every year I do the <a target="_blank" rel="noopener" href="https://adventofcode.com/" onclick="return trackOutboundLink('recent blog posts', 'https://adventofcode.com/', event);">Advent of Code</a> in a different programming language. If you aren&#39;t familiar, it&#39;s an online coding competition with a new two-part problem every day from December 1st to the 25th. Thousands of programmers participate and share their solutions. It&#39;s a great way to learn a language and bond over coding. In <a target="_blank" rel="noopener" href="https://danvdk.medium.com/python-tips-tricks-for-the-advent-of-code-2019-89ec23a595dd" onclick="return trackOutboundLink('recent blog posts', 'https://danvdk.medium.com/python-tips-tricks-for-the-advent-of-code-2019-89ec23a595dd', event);">2019</a> I used Python, in <a target="_blank" rel="noopener" href="https://danvdk.medium.com/advent-of-code-2020-this-time-in-rust-7904559e24bc" onclick="return trackOutboundLink('recent blog posts', 'https://danvdk.medium.com/advent-of-code-2020-this-time-in-rust-7904559e24bc', event);">2020</a> I used Rust and in <a href="https://effectivetypescript.com/2022/02/06/advent-of-code-2021-golang/">2021</a> I used Go. I also post an increasingly-belated writeup of my experience and impressions of the language so, at the end of April, here&#39;s 2022! (As a partial excuse, I have been writing on a <a target="_blank" rel="noopener" href="https://danvk.org/catskills/" onclick="return trackOutboundLink('recent blog posts', 'https://danvk.org/catskills/', event);">very different blog</a>!)</p>
<p>This past December I chose TypeScript, specifically <a target="_blank" rel="noopener" href="https://deno.land" onclick="return trackOutboundLink('recent blog posts', 'https://deno.land', event);">Deno</a>, which <a target="_blank" rel="noopener" href="https://www.youtube.com/watch?v=1gIiZfSbEAE" onclick="return trackOutboundLink('recent blog posts', 'https://www.youtube.com/watch?v=1gIiZfSbEAE', event);">brands itself</a> as &quot;a new way to TypeScript&quot;. While TypeScript certainly isn&#39;t a new language for me, Deno is a new way to use it. I was also curious how JavaScript/TypeScript would do on AoC-style coding competitions and, frankly, I hadn&#39;t been doing much coding of late and was keen to have an excuse to use my favorite language more.</p>
<p>This post is broken into three parts: thoughts on Deno, thoughts on TypeScript/JavaScript for coding competitions, and my thoughts on this year&#39;s Advent of Code.</p>
<a class="read-more" href="/2023/04/27/aoc2022/">Continue&nbsp;reading&nbsp;&raquo;</a>

</div>
</div>
</div>



<div class="row">
<div class="col-md-12">
Expand Down
46 changes: 24 additions & 22 deletions archives/page/2/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,30 @@ <h2>Recent Blog Posts</h2>

<div class="container">

<div class="row hentry" id="aoc2022">
<div class="col-md-12">
<h3 class="entry-title">
<a href="/2023/04/27/aoc2022/">A first look at Deno through the Advent of Code 2022</a>
</h3>

<div class="text-muted published-container">
<time class="published" datetime="2023-04-27T21:00:00.000Z" itemprop="datePublished">
Thu 27 April 2023
</time>
</div>

<div class="entry-content">

<p><img src="https://effectivetypescript.com/images/advent-of-code.png" title="Advent of Code Logo" width="64" height="64" style="float: right; margin-left: 10px;">Every year I do the <a target="_blank" rel="noopener" href="https://adventofcode.com/" onclick="return trackOutboundLink('recent blog posts', 'https://adventofcode.com/', event);">Advent of Code</a> in a different programming language. If you aren&#39;t familiar, it&#39;s an online coding competition with a new two-part problem every day from December 1st to the 25th. Thousands of programmers participate and share their solutions. It&#39;s a great way to learn a language and bond over coding. In <a target="_blank" rel="noopener" href="https://danvdk.medium.com/python-tips-tricks-for-the-advent-of-code-2019-89ec23a595dd" onclick="return trackOutboundLink('recent blog posts', 'https://danvdk.medium.com/python-tips-tricks-for-the-advent-of-code-2019-89ec23a595dd', event);">2019</a> I used Python, in <a target="_blank" rel="noopener" href="https://danvdk.medium.com/advent-of-code-2020-this-time-in-rust-7904559e24bc" onclick="return trackOutboundLink('recent blog posts', 'https://danvdk.medium.com/advent-of-code-2020-this-time-in-rust-7904559e24bc', event);">2020</a> I used Rust and in <a href="https://effectivetypescript.com/2022/02/06/advent-of-code-2021-golang/">2021</a> I used Go. I also post an increasingly-belated writeup of my experience and impressions of the language so, at the end of April, here&#39;s 2022! (As a partial excuse, I have been writing on a <a target="_blank" rel="noopener" href="https://danvk.org/catskills/" onclick="return trackOutboundLink('recent blog posts', 'https://danvk.org/catskills/', event);">very different blog</a>!)</p>
<p>This past December I chose TypeScript, specifically <a target="_blank" rel="noopener" href="https://deno.land" onclick="return trackOutboundLink('recent blog posts', 'https://deno.land', event);">Deno</a>, which <a target="_blank" rel="noopener" href="https://www.youtube.com/watch?v=1gIiZfSbEAE" onclick="return trackOutboundLink('recent blog posts', 'https://www.youtube.com/watch?v=1gIiZfSbEAE', event);">brands itself</a> as &quot;a new way to TypeScript&quot;. While TypeScript certainly isn&#39;t a new language for me, Deno is a new way to use it. I was also curious how JavaScript/TypeScript would do on AoC-style coding competitions and, frankly, I hadn&#39;t been doing much coding of late and was keen to have an excuse to use my favorite language more.</p>
<p>This post is broken into three parts: thoughts on Deno, thoughts on TypeScript/JavaScript for coding competitions, and my thoughts on this year&#39;s Advent of Code.</p>
<a class="read-more" href="/2023/04/27/aoc2022/">Continue&nbsp;reading&nbsp;&raquo;</a>

</div>
</div>
</div>


<div class="row hentry" id="ts-50-beta">
<div class="col-md-12">
<h3 class="entry-title">
Expand Down Expand Up @@ -361,28 +385,6 @@ <h3 class="entry-title">
</div>


<div class="row hentry" id="interface">
<div class="col-md-12">
<h3 class="entry-title">
<a href="/2021/06/03/interface/">In defense of interface: Using declaration merging to disable &#34;bad parts&#34;</a>
</h3>

<div class="text-muted published-container">
<time class="published" datetime="2021-06-03T21:00:56.000Z" itemprop="datePublished">
Thu 03 June 2021
</time>
</div>

<div class="entry-content">

<p>TypeScript&#39;s <code>interface</code> has gotten a bit of a <a target="_blank" rel="noopener" href="https://twitter.com/kentcdodds/status/1392678508954980353" onclick="return trackOutboundLink('recent blog posts', 'https://twitter.com/kentcdodds/status/1392678508954980353', event);">bad rap</a> lately, largely because of <a target="_blank" rel="noopener" href="https://www.typescriptlang.org/docs/handbook/declaration-merging.html" onclick="return trackOutboundLink('recent blog posts', 'https://www.typescriptlang.org/docs/handbook/declaration-merging.html', event);">declaration merging</a>, a behavior of <code>interface</code> that&#39;s quite surprising when you first see it. This post explains what declaration merging is, <em>why</em> it is, and how you can use it to iron out some of JavaScript&#39;s and TypeScript&#39;s wrinkles in your own projects.</p>
<a class="read-more" href="/2021/06/03/interface/">Continue&nbsp;reading&nbsp;&raquo;</a>

</div>
</div>
</div>



<div class="row">
<div class="col-md-12">
Expand Down
47 changes: 22 additions & 25 deletions archives/page/3/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,28 @@ <h2>Recent Blog Posts</h2>

<div class="container">

<div class="row hentry" id="interface">
<div class="col-md-12">
<h3 class="entry-title">
<a href="/2021/06/03/interface/">In defense of interface: Using declaration merging to disable &#34;bad parts&#34;</a>
</h3>

<div class="text-muted published-container">
<time class="published" datetime="2021-06-03T21:00:56.000Z" itemprop="datePublished">
Thu 03 June 2021
</time>
</div>

<div class="entry-content">

<p>TypeScript&#39;s <code>interface</code> has gotten a bit of a <a target="_blank" rel="noopener" href="https://twitter.com/kentcdodds/status/1392678508954980353" onclick="return trackOutboundLink('recent blog posts', 'https://twitter.com/kentcdodds/status/1392678508954980353', event);">bad rap</a> lately, largely because of <a target="_blank" rel="noopener" href="https://www.typescriptlang.org/docs/handbook/declaration-merging.html" onclick="return trackOutboundLink('recent blog posts', 'https://www.typescriptlang.org/docs/handbook/declaration-merging.html', event);">declaration merging</a>, a behavior of <code>interface</code> that&#39;s quite surprising when you first see it. This post explains what declaration merging is, <em>why</em> it is, and how you can use it to iron out some of JavaScript&#39;s and TypeScript&#39;s wrinkles in your own projects.</p>
<a class="read-more" href="/2021/06/03/interface/">Continue&nbsp;reading&nbsp;&raquo;</a>

</div>
</div>
</div>


<div class="row hentry" id="unsoundness">
<div class="col-md-12">
<h3 class="entry-title">
Expand Down Expand Up @@ -356,31 +378,6 @@ <h3 class="entry-title">
</div>


<div class="row hentry" id="tsprune">
<div class="col-md-12">
<h3 class="entry-title">
<a href="/2020/10/20/tsprune/">Finding dead code (and dead types) in TypeScript</a>
</h3>

<div class="text-muted published-container">
<time class="published" datetime="2020-10-20T22:20:56.000Z" itemprop="datePublished">
Tue 20 October 2020
</time>
</div>

<div class="entry-content">

<p>Software engineering is a battle against complexity. Without any planning or care, it&#39;s easy to build programs where everything interacts with everything else (the &quot;big ball of yarn&quot; model). With a ball of yarn, if you double the number of components, you quadruple the number of interactions:</p>
<img src="https://effectivetypescript.com/images/quadratic.png" alt="Complexity increases with the number of interactions, i.e. quadratically" width="439" height="262">

<p>One of the best ways to fight against this ramp-up of complexity is to simply reduce N, i.e. to write fewer lines of code. Using a higher level programming language or depending on well-tested third-party libraries are common ways to do this. But one of the easiest ways is to find code you don&#39;t need any more and delete it.</p>
<a class="read-more" href="/2020/10/20/tsprune/">Continue&nbsp;reading&nbsp;&raquo;</a>

</div>
</div>
</div>



<div class="row">
<div class="col-md-12">
Expand Down
57 changes: 25 additions & 32 deletions archives/page/4/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,31 @@ <h2>Recent Blog Posts</h2>

<div class="container">

<div class="row hentry" id="tsprune">
<div class="col-md-12">
<h3 class="entry-title">
<a href="/2020/10/20/tsprune/">Finding dead code (and dead types) in TypeScript</a>
</h3>

<div class="text-muted published-container">
<time class="published" datetime="2020-10-20T22:20:56.000Z" itemprop="datePublished">
Tue 20 October 2020
</time>
</div>

<div class="entry-content">

<p>Software engineering is a battle against complexity. Without any planning or care, it&#39;s easy to build programs where everything interacts with everything else (the &quot;big ball of yarn&quot; model). With a ball of yarn, if you double the number of components, you quadruple the number of interactions:</p>
<img src="https://effectivetypescript.com/images/quadratic.png" alt="Complexity increases with the number of interactions, i.e. quadratically" width="439" height="262">

<p>One of the best ways to fight against this ramp-up of complexity is to simply reduce N, i.e. to write fewer lines of code. Using a higher level programming language or depending on well-tested third-party libraries are common ways to do this. But one of the easiest ways is to find code you don&#39;t need any more and delete it.</p>
<a class="read-more" href="/2020/10/20/tsprune/">Continue&nbsp;reading&nbsp;&raquo;</a>

</div>
</div>
</div>


<div class="row hentry" id="prop-drilling">
<div class="col-md-12">
<h3 class="entry-title">
Expand Down Expand Up @@ -352,38 +377,6 @@ <h3 class="entry-title">
</div>


<div class="row hentry" id="jsonify">
<div class="col-md-12">
<h3 class="entry-title">
<a href="/2020/04/09/jsonify/">What&#39;s the type of JSON.parse(​JSON.stringify(x))?</a>
</h3>

<div class="text-muted published-container">
<time class="published" datetime="2020-04-09T15:00:56.000Z" itemprop="datePublished">
Thu 09 April 2020
</time>
</div>

<div class="entry-content">

<p>If you&#39;re writing a server in JavaScript, you might write an endpoint that converts an object to JSON:</p>
<!-- verifier:skip to avoid express dep -->
<figure class="highlight ts"><table><tr><td class="code"><pre><code class="hljs ts">app.get(<span class="hljs-string">&#x27;/user&#x27;</span>, <span class="hljs-function">(<span class="hljs-params">request, response</span>) =&gt;</span> &#123;<br> <span class="hljs-keyword">const</span> user = getCurrentUser();<br> response.json(user);<br>&#125;);<br></code></pre></td></tr></table></figure>

<p>On the client, you might use the <code>fetch</code> API to hit this endpoint and deserialize (parse) the data:</p>
<!-- verifier:tsconfig:module=esnext -->
<!-- verifier:tsconfig:target=esnext -->
<!-- verifier:skip until top-level await works -->
<figure class="highlight ts"><table><tr><td class="code"><pre><code class="hljs ts"><span class="hljs-keyword">const</span> response = <span class="hljs-keyword">await</span> fetch(<span class="hljs-string">&#x27;/user&#x27;</span>);<br><span class="hljs-keyword">const</span> user = <span class="hljs-keyword">await</span> response.json();<br></code></pre></td></tr></table></figure>

<p>What&#39;s the relationship between the <code>user</code> object in the server and the corresponding <code>user</code> object in the client? And how would you model this in TypeScript?</p>
<a class="read-more" href="/2020/04/09/jsonify/">Continue&nbsp;reading&nbsp;&raquo;</a>

</div>
</div>
</div>



<div class="row">
<div class="col-md-12">
Expand Down
32 changes: 32 additions & 0 deletions archives/page/5/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,38 @@ <h2>Recent Blog Posts</h2>

<div class="container">

<div class="row hentry" id="jsonify">
<div class="col-md-12">
<h3 class="entry-title">
<a href="/2020/04/09/jsonify/">What&#39;s the type of JSON.parse(​JSON.stringify(x))?</a>
</h3>

<div class="text-muted published-container">
<time class="published" datetime="2020-04-09T15:00:56.000Z" itemprop="datePublished">
Thu 09 April 2020
</time>
</div>

<div class="entry-content">

<p>If you&#39;re writing a server in JavaScript, you might write an endpoint that converts an object to JSON:</p>
<!-- verifier:skip to avoid express dep -->
<figure class="highlight ts"><table><tr><td class="code"><pre><code class="hljs ts">app.get(<span class="hljs-string">&#x27;/user&#x27;</span>, <span class="hljs-function">(<span class="hljs-params">request, response</span>) =&gt;</span> &#123;<br> <span class="hljs-keyword">const</span> user = getCurrentUser();<br> response.json(user);<br>&#125;);<br></code></pre></td></tr></table></figure>

<p>On the client, you might use the <code>fetch</code> API to hit this endpoint and deserialize (parse) the data:</p>
<!-- verifier:tsconfig:module=esnext -->
<!-- verifier:tsconfig:target=esnext -->
<!-- verifier:skip until top-level await works -->
<figure class="highlight ts"><table><tr><td class="code"><pre><code class="hljs ts"><span class="hljs-keyword">const</span> response = <span class="hljs-keyword">await</span> fetch(<span class="hljs-string">&#x27;/user&#x27;</span>);<br><span class="hljs-keyword">const</span> user = <span class="hljs-keyword">await</span> response.json();<br></code></pre></td></tr></table></figure>

<p>What&#39;s the relationship between the <code>user</code> object in the server and the corresponding <code>user</code> object in the client? And how would you model this in TypeScript?</p>
<a class="read-more" href="/2020/04/09/jsonify/">Continue&nbsp;reading&nbsp;&raquo;</a>

</div>
</div>
</div>


<div class="row hentry" id="null-values-to-perimeter">
<div class="col-md-12">
<h3 class="entry-title">
Expand Down
Loading

0 comments on commit 36a8a84

Please sign in to comment.