Swizec Teller - a geek with a hatswizec.com

Senior Mindset Book

Get promoted, earn a bigger salary, work for top companies

Senior Engineer Mindset cover
Learn more

    TypeScript's biggest flaw and how you can use ducks to fix it

    TypeScript is wonderful. Been using it more and more and I love it. 🥰

    There's something magical about useful autocomplete suggestions, object blobs with property hints, and auto imports. That's right, auto imports.

    3It1RzR

    Press enter and VSCode adds import { FieldTypes } from './types' at the top.

    And check this out: I got a form builder that takes JavaScript blobs as configuration. VSCode is smart enough to tell me when they're wrong. 👌

    This works:

    8jAnn0L

    Got a field with a name and a placeholder. Remove one and o-oh.

    ulnjYvE

    The error is cryptic type vomit. You get used to that. Means that one of your blobs doesn't match any known field type.

    But get this, add type: "email" and no need for a placeholder 😮

    43vXqhT

    Whoa

    whoa giphy

    So what's going on here? What's TypeScript doing to support this? And why do we need a type property if we're using a typed language?

    Static analysis

    Static analysis is where TypeScript shines. Its main design goal 👉 enable static analysis of JavaScript

    Static program analysis is the analysis of computer software that is performed without actually executing programs, in contrast with dynamic analysis, which is analysis performed on programs while they are executing.

    Static analysis uses static types to understand your code. Editors use this understanding to help you write better code.

    Everything from autocompletion, hints on object properties, and squiggly lines when you get something wrong. Some editors even integrate with documentation and give you help right in the editor.

    TypeScript with VSCode brings all that to JavaScript.

    You get a better coding experience most of the time. Sometimes you fight the type system, but it's got your back ... mostly. Great for large teams and large codebases.

    Know your code has at least a remote chance of being correct without running every single line? Love it ❤️

    Dynamic analysis

    In contrast to static analysis you have dynamic analysis. That's JavaScript's normal mode.

    Dynamic program analysis is the analysis of computer software that is performed by executing programs on a real or virtual processor. For dynamic program analysis to be effective, the target program must be executed with sufficient test inputs to produce interesting behavior.

    To analyze a dynamic language, you gotta run it. That's where test driven development comes in.

    You don't have a static type system saving your butt for some classes of errors. You gotta run the thing and see if it works. And you better make sure you run every line of code.

    If you don't, I promise your users will 😉

    Duck typing

    duck giphy

    Duck typing is a strange beast most popular in the land of Lisp. It falls under dynamic typing, but statically typed duck languages exist also. Wikipedia classifies it as the 4th major category next to static, dynamic, and nominal typing.

    If it walks like a duck and it quacks like a duck, then it must be a duck

    The duck test 🦆

    You're duck typing every time you write code like if (object.property && object.property.value === 'something')

    Verify the object is a duck, has a property, then use it like a duck.

    Type guards in TypeScript

    That brings us to TypeScript's biggest flaw.

    From TypeScript Design Goals

    Impose no runtime overhead on emitted programs. Emit clean, idiomatic, recognizable JavaScript code.

    TypeScript is a static analysis tool only. No types at runtime. No type checking. No validations. Nothing.

    Great for program size and understandability. Not great for useful type system.

    Say you've got a form builder with two field types like I mentioned before.

    Click through for source
    Click through for source

    A union FieldTypes type saves typing in a bunch of places.

    Then we got a CoreFieldProps interface that defines properties all fields share. Every field needs a name, optionally an initialValue too.

    Specific field types extend the core props and add their own. Most importantly they add the type field.

    That's how TypeScript knows what you mean when you write

    Click through for source
    Click through for source

    Looks at the first two blobs, sees they match TextFieldProps. They've got a name and a placeholder, no type.

    The last blob uses type: "email" so TypeScript knows it's okay that there's no placeholder. Optional in emails.

    Duck typing at runtime

    Static analysis worked great in the editor. What about when you want to render different fields based on their type?

    You're using a typed language right, how hard can it be.

    Click through for source
    Click through for source

    Not so fast buster.

    JavaScript has no idea about your types. typeof props evaluates to object. That's not gonna match your artisanally crafted types you worked so hard to build 😉

    Instead, you'll have to use TypeScript Type Guards

    Two types of guards prove useful in the wild:

    1. Duck typing
    2. Explicit type property

    Duck typing

    A duck typed type guard uses the duck test. If property exists on object, do the things.

    Click through for source
    Click through for source

    An animal is a duck if it can both swim and fly. The in operator checks for the existence of a key (or property) on an object.

    Explicit type property

    The other approach works best in an object blob situation. You provide a type attribute, define types with hardcoded values, then make sure they're defined.

    Use those values at runtime to decide what to do

    Click through for source
    Click through for source

    An object constructor can help too. new EmailFieldProps() and it sets this.type to email by default.

    But I prefer blobs for passing data and use duck typing when dealing with actual objects. If it can do what I need, what do I care what type it is?

    Quack

    kr3gtct

    And that's how you can use ducks to solve TypeScript's biggest flaw – lack of type support at runtime.

    Hope this was useful ✌️

    Cheers,
    ~Swizec

    Published on June 17th, 2019 in Computer Science, Front End, Technical

    Did you enjoy this article?

    Continue reading about TypeScript's biggest flaw and how you can use ducks to fix it

    Semantically similar articles hand-picked by GPT-4

    Senior Mindset Book

    Get promoted, earn a bigger salary, work for top companies

    Learn more

    Have a burning question that you think I can answer? Hit me up on twitter and I'll do my best.

    Who am I and who do I help? I'm Swizec Teller and I turn coders into engineers with "Raw and honest from the heart!" writing. No bullshit. Real insights into the career and skills of a modern software engineer.

    Want to become a true senior engineer? Take ownership, have autonomy, and be a force multiplier on your team. The Senior Engineer Mindset ebook can help 👉 swizec.com/senior-mindset. These are the shifts in mindset that unlocked my career.

    Curious about Serverless and the modern backend? Check out Serverless Handbook, for frontend engineers 👉 ServerlessHandbook.dev

    Want to Stop copy pasting D3 examples and create data visualizations of your own? Learn how to build scalable dataviz React components your whole team can understand with React for Data Visualization

    Want to get my best emails on JavaScript, React, Serverless, Fullstack Web, or Indie Hacking? Check out swizec.com/collections

    Did someone amazing share this letter with you? Wonderful! You can sign up for my weekly letters for software engineers on their path to greatness, here: swizec.com/blog

    Want to brush up on your modern JavaScript syntax? Check out my interactive cheatsheet: es6cheatsheet.com

    By the way, just in case no one has told you it yet today: I love and appreciate you for who you are ❤️

    Created by Swizec with ❤️