Type checking is a process in programming languages that ensures variables are used consistently with their declared types, preventing type errors during execution. It can be performed at compile-time (static type checking) or at runtime (dynamic type checking), each offering different trade-offs in terms of performance and flexibility.