What you’re not seeing is that TS is a structurally typed language, not a nominally typed language. Two type signatures defined in different places with a different name may be assignable to each other - so typescript usually has to deep-compare, recursively, the two types until a conflicting field is found.
TypeScript team member here: the structures are arbitrarily deep and recursive. Also, as explained in a sibling comment, it's not just about type identity, but type assignability.
Hashing lets you know whether it's the same type or two different types, but you still need to look at the members to find out whether one is a subtype of the other.