Los lenguajes de tipo estático generalmente requieren que declare los tipos de variables, que luego se verifican en tiempo de compilación para reducir los errores. La palabra "estático" en "estáticamente tipado" se refiere al "análisis de código estático", que es el proceso de examinar el código antes de ejecutarlo. Aunque es posible que un lenguaje de tipo estático infiera el tipo de la variable desde el lado derecho de una expresión o parámetros reales, en la práctica la mayoría de los lenguajes de tipo estático requieren que los tipos de variables se declaren explícitamente.
Los lenguajes de tipo dinámico generalmente no requieren que las declaraciones de variables tengan tipos, e infieren tipos de variables basados en el tipo calculado como resultado de evaluar el lado derecho de cada declaración de asignación o los parámetros reales de una llamada a función. Dado que a la variable se le pueden asignar múltiples tareas durante su vida útil, su tipo puede cambiar con el tiempo y es por eso que se llama "tipeado dinámicamente". Además, el entorno de tiempo de ejecución necesita realizar un seguimiento del tipo actual para cada variable, por lo que el tipo está vinculado al valor en lugar de a la declaración de la variable. Esto puede considerarse un sistema de información de tipo de tiempo de ejecución (RTTI).
Se pueden combinar elementos de lenguajes tipados estática y dinámicamente. Por ejemplo, C # admite variables tipadas estáticamente y dinámicamente, y los lenguajes orientados a objetos generalmente admiten la conversión descendente de la jerarquía de tipos. Los lenguajes de tipo estático suelen proporcionar varias formas de evitar la verificación de tipos, por ejemplo, mediante el uso de la conversión, la reflexión y la invocación dinámica.
Typing Strong vs. Weak Typing se refiere a un continuo de cuánto intenta el lenguaje evitar errores debido al uso de una variable como si fuera un tipo cuando en realidad es otro tipo. Por ejemplo, tanto C como Java son lenguajes de tipo estático, sin embargo, Java utiliza una verificación de tipos mucho más fuerte que C. El siguiente código C se compila y ejecuta, y pondrá un valor aleatorio en la variable b en tiempo de ejecución, lo que probablemente causará un insecto:
char *a = "123";
int b = (int)a;
El código Java equivalente producirá un error de compilación, que generalmente es preferible:
String a = "123"
int b = (int)a;