Annotated solution
Published September 9, 2026The solution
type Invert<T extends Record<string, string>> = { [K in keyof T as T[K]]: K }The common wrong answer
type Invert<T extends Record<string, string>> = { [K in keyof T as T[K]]: T[K] }Half the swap. The key is renamed to the old value, which is right, and then the value is set to the old value as well — producing { x: "x" } where the check wants { x: "a" }. Renaming a key does not move the old key anywhere; if you want it, you have to put it in the value clause yourself.
Line by line
as T[K]The new key is the old value.
asaccepts any expression that produces a key type, and an indexed access is one.: KAnd the new value is the old key, still in scope, still a literal. The two clauses are independent — which is what makes a clean swap possible in one line.
Takeaway
A mapped type makes two separate decisions per key: what it is called, and what it holds. Most mapped-type bugs are one of those two answers accidentally reused for the other.

