Testing types in TypeScript
Assertions that run in the compiler, not at run time.
type Equal<A, B> =
(<T>() => T extends A ? 1 : 2) extends <T>() => T extends B ? 1 : 2
? true
: false;
type Expect<T extends true> = T;
type Pluck<T, K extends keyof T> = T[K];
interface Run {
lang: string;
tpm: number;
}
type _keys = Expect<Equal<keyof Run, "lang" | "tpm">>;
type _value = Expect<Equal<Pluck<Run, "tpm">, number>>;
type _notAny = Expect<Equal<Pluck<Run, "lang">, string>>;
function stars(tpm: number): 1 | 3 {
return tpm >= 100 ? 3 : 1;
}
type _return = Expect<Equal<ReturnType<typeof stars>, 1 | 3>>;
// @ts-expect-error a string is not a number
const wrong: number = "98";
console.log(stars(104), typeof wrong);
How it works
Equalcompares two types exactly, not just assignability.Expectfails to compile when the check is false.- A
@ts-expect-errorcomment asserts that something must not compile.
Keywords and builtins used here
constextendsfalsefunctioninterfacenumberreturnstringtype
The run, in numbers
- Lines
- 28
- Characters to type
- 639
- Tokens
- 190
- Three-star pace
- 110 tpm
At the three-star pace of 110 tokens a minute, this run takes about 104 seconds.
Step 3 of 3 in Exhaustiveness & tests, step 11 of 12 in Type-level programming.