No. The TypeScript Design Goals list "apply a sound or provably correct type system" as a non-goal: the aim is "a balance between correctness and productivity". The Handbook's compatibility page says the same, calling out places where the system allows operations it cannot prove safe, and explains the motivating cases.
The holes I would name, each of which compiled under strict and then failed at runtime:
anyswitches checking off for a value, and anything assigns to or from it.unknownis the safe top type.- Type assertions (
as,!) are claims the compiler trusts. They are erased and never checked. - Array covariance.
Dog[]is assignable toAnimal[], so you can push aCatthrough the wider alias. The same applies to mutable object properties. - Method parameter bivariance.
strictFunctionTypeschecks function-typed properties contravariantly but not method declarations; the FAQ calls this "working as intended" because making methods strict breaks idiomatic patterns, including array covariance. - Index signatures and array indexing type
obj[key]as the value type withoutundefined.noUncheckedIndexedAccessadds it. - Narrowing across calls. After
if (o.v !== null), a function call that nullso.vdoes not undo the narrowing (the last case in my run:Cannot read properties of null (reading 'length')). Issue #9998 weighs assuming calls do nothing against assuming they reset every narrowing, and finds wrong results either way on real code. - Boundaries.
JSON.parse, third-partyanyand wrong.d.tsfiles inject unchecked data (see the type-erasure question).
Practical stance: treat TypeScript as a strong bug-catcher, not a proof. Close the cheap holes with strict, noUncheckedIndexedAccess, unknown over any, readonly arrays/parameters, function-typed properties for callbacks, and runtime validation at boundaries.