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.
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:
Got a field with a name
and a placeholder
. Remove one and o-oh.
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 😮
Whoa
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 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.
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.
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
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.
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:
- Duck typing
- Explicit
type
property
Duck typing
A duck typed type guard uses the duck test. If property exists on object, do the things.
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
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
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
Continue reading about TypeScript's biggest flaw and how you can use ducks to fix it
Semantically similar articles hand-picked by GPT-4
- Learn TypeScript in 5 minutes
- The efficacy of TypeScript
- TypeScript runtime vs types at run-time
- How to configure Jest with TypeScript
- TypeScript for serverless lambda backends 👌
Learned something new?
Read more Software Engineering Lessons from Production
I write articles with real insight into the career and skills of a modern software engineer. "Raw and honest from the heart!" as one reader described them. Fueled by lessons learned over 20 years of building production code for side-projects, small businesses, and hyper growth startups. Both successful and not.
Subscribe below 👇
Software Engineering Lessons from Production
Join Swizec's Newsletter and get insightful emails 💌 on mindsets, tactics, and technical skills for your career. Real lessons from building production software. No bullshit.
"Man, love your simple writing! Yours is the only newsletter I open and only blog that I give a fuck to read & scroll till the end. And wow always take away lessons with me. Inspiring! And very relatable. 👌"
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 ❤️