TypeScript Typing Drill
< > : | ? ( ) { } =
Every passage contains: < > : | ? ( ) { } =
QWERTY layout assumed. Backspace corrects; uncorrected errors count against net WPM.
const rows: Array<Record<string, number>> = []; nests one generic inside another, and closing it means two consecutive shifted presses on the right ring finger — a shift-held same-finger repeat with no letter between the two, similar in shape to the double colon the Rust Typing Drill asks the right pinky for, though built from a different key and a different piece of syntax entirely. const cache = new Map<string, Row[]>(); only nests one level deep, so the same closing motion happens just once rather than twice.
The question mark does three unrelated jobs across this drill's short passage. function load(id?: number) uses it to mark a parameter as optional. const size = options?.size ?? 10; uses it twice more — once to check a property safely before reading it, and twice in a row, unshifted key repeated with Shift held both times, to supply a fallback if the result is missing. None of these three uses means "is this a question," which is the only job the Email & URL Character Drill's query strings or ordinary sentence punctuation ever ask of the same key.
A line like export type Mode = 'read' | 'write' | 'append'; adds a fourth character on top of JavaScript's own load: the pipe, reached with Shift on the right pinky, appearing twice in one line to separate three quoted options from each other.
Why This Drill
Array<Record<string, number>>'s closing >> asks the right ring finger to fire twice under Shift with nothing between the two presses, a heavier version of the single greater-than the JavaScript Typing Drill's arrow syntax uses only once per occurrence. Getting that double press wrong — releasing Shift a beat early, or letting a single press stand in for two — closes only one of the two open generics and leaves code that won't compile.
The question mark's three jobs matter because none of them look alike on the page even though they're the identical keystroke. A typist fluent with this key from ordinary sentences, or from the query strings the Email & URL Character Drill drills separately, still has to relearn what it means moment to moment here — optional parameter, safe property access, or fallback value — since nothing about the character itself tells them which.
The pipe is worth its own note because so few typists press it outside a terminal window. 'read' | 'write' | 'append' uses it as an ordinary piece of type syntax, tight against quoted strings on either side with just a space for breathing room — a different rhythm from the same key's use in the Shell Command Typing Drill, where it chains whole commands together rather than separating three short words.
Two Levels of Angle Brackets, Closing on the Same Finger Twice
Map<string, Row[]> closes with a single greater-than. Array<Record<string, number>> nests one generic inside another and closes with two in a row, both produced by the right ring finger under Shift with no letter separating them — the identical finger, doing the identical motion twice, purely because the type itself is nested one level deeper.
One Key, Three Unrelated Jobs in a Few Short Lines
id?: number marks a parameter optional. options?.size checks a property safely before reading from it. ?? 10 supplies a fallback when the result comes back empty. Three different meanings, the same shift-plus-slash keystroke each time, distinguished only by what sits immediately before and after it on the line.
A Pipe Doing the Work a Comma Might Do Elsewhere
'read' | 'write' | 'append' uses the pipe to separate three alternatives the way a comma separates items in an ordinary list, except this character needs Shift and sits on the far right edge of the keyboard rather than under the right middle finger the way a comma does. Two pipes appear in this one line, each bordered by a space and a quoted word rather than typed loose against surrounding text.
Where JavaScript's Load Gets a Second Layer
Everything the JavaScript Typing Drill covers — the arrow, the braces, the backtick — still applies here. Angle brackets and the pipe stack directly on top of that existing load rather than replacing any of it, which is the real reason a short line of annotated TypeScript can carry more distinct shift transitions than an equivalent line of plain JavaScript.
Frequently Asked Questions
Why does closing Array<Record<string, number>> feel harder than closing a single generic like Map<string, Row[]>?
The nested version needs two greater-than presses in a row, both from the right ring finger under Shift with nothing between them, rather than the single press a one-level generic requires — a same-finger repeat that's easy to under-count.
Does the question mark always mean the same thing in TypeScript?
No. This drill's passage alone uses it for three different jobs — an optional parameter, a safe property check, and a fallback value — and the keystroke gives no hint on its own about which one applies.
Is the pipe in a union type the same keystroke as the pipe in a shell command?
The exact same key and finger, but a different rhythm. Here it sits tight against quoted words with just a single space on either side; the Shell Command Typing Drill uses it to chain entire commands together instead of short alternatives.
Why does this drill cover angle brackets separately from the Bracket & Parenthesis Drill?
That drill isolates round, square and curly pairs on their own, without any code syntax around them. Angle brackets here always appear attached to a type name, often nested, which is a different motor task from a bare pair sitting on its own.
How is this different from typing plain JavaScript?
It is not a replacement, it is an addition. Everything JavaScript demands is still there, with angle brackets and pipes layered on top.
Why does options?.size use a question mark right after options, with no space?
That's the optional-chaining form — it checks whether options exists before trying to read a property from it, and the mark has to sit immediately against the variable name for the check to apply to it correctly.