Assertions and their cost in TypeScript
as, non-null, and the two escape hatches you should distrust.
const raw: unknown = JSON.parse('{"lang":"ts"}');
const risky = raw as { lang: string };
console.log(risky.lang.toUpperCase()); // trusted, unchecked
const rows: (string | null)[] = ["a", null];
const first = rows[0]!;
console.log(first.length);
function narrow(value: unknown): { lang: string } {
if (typeof value !== "object" || value === null || !("lang" in value)) {
throw new TypeError("no lang");
}
const { lang } = value as { lang: unknown };
if (typeof lang !== "string") throw new TypeError("lang is not a string");
return { lang };
}
console.log(narrow(raw).lang);
const widened = "monokai" as const satisfies string;
const doubled = <T,>(value: T): [T, T] => [value, value];
console.log(widened, doubled(1));
How it works
asreinterprets without checking; it can lie.!asserts non-null and crashes at run time when wrong.- A validating function is the honest alternative.
Keywords and builtins used here
JSONTasconstfunctionifreturnstringthrowunknown
The run, in numbers
- Lines
- 23
- Characters to type
- 724
- Tokens
- 204
- Three-star pace
- 90 tpm
At the three-star pace of 90 tokens a minute, this run takes about 136 seconds.
Step 2 of 2 in The awkward types, step 6 of 23 in Types & annotations.