Type Systems: Static and Dynamic Typing

Catch the wrong kind of mark before it reaches a report

A science mark should be numeric, but a program accidentally replaces 35 with the text '35'. Adding a correction can then join text instead of calculating a new mark. When can a tool identify this mismatch?

A type system defines rules for the types of values and their permitted use. Static type checking analyzes code before execution. In dynamic typing, operations use the actual types of values while the program runs. Both approaches still have typed values and language rules.

  1. Compare checking times

    Explain what a static checker can detect before execution and how dynamic values behave during execution.

  2. Read an inferred type

    Recognize that a checker can infer a type without an explicit annotation.

  3. Know the limit

    Distinguish type correctness from valid school data, and avoid confusing typing with const or compilation.

A text value reaches a numeric mark

  1. Intended data

    The mark begins as a numeric value.

    science → 35
  2. Static check

    A TypeScript number variable rejects a later string assignment.

    Type mismatch before execution
  3. JavaScript execution

    A let name can hold a string later; addition now follows string rules.

    "35" + 5 → "355"
This comparison describes the shown JavaScript and TypeScript examples, not the rules of every language.

A rule can reject a value—or define how to use it

A type system is more than a list of names such as number and string. It also describes which operations and combinations are allowed. For example, a language can reject adding text to a number, or define an automatic conversion for that operation.

Static checking uses information available from source code to reason about types before execution. Dynamic execution uses the actual values present at that point. A dynamic language can report a type-related error at runtime, but an allowed conversion may instead produce a result you did not intend.

The prerequisites are basic value types and assignment and reassignment. Our school examples use the same numeric mark and quoted digits so the difference stays visible.

JavaScript permits this name to hold a different type

This complete example is JavaScript. let permits reassignment, and JavaScript allows this name to refer to a number first and a string later. typeof displays the type of each current value.

The final result is the string 355, not the corrected numeric mark 40. This is permitted JavaScript behavior: the string leads + to join text. Dynamic typing does not mean values have no types, and a surprising result does not necessarily cause an exception.

JavaScript · local teaching example

let science = 35;
console.log(typeof science);
science = '35';
console.log(typeof science);
console.log(science + 5);

Expected output

number
string
355

TypeScript can reject the incompatible assignment

This version uses TypeScript, a language that adds static checking to JavaScript. The : number after the variable name is a type annotation: this name is expected to hold numeric values.

let science: number = 35;
science = '35';
console.log(science + 5);

Save this as student-mark.ts. With the TypeScript compiler installed, use this shell command to check it without producing a runnable output file:

tsc --strict --noEmit student-mark.ts

Expected result: a type-checking diagnostic on the string assignment, stating that string is not assignable to number. This command checks the source; it does not run the console output. Exact diagnostic formatting depends on the compiler version.

The annotation does not convert '35' into 35. It expresses a constraint and helps a tool identify a mismatch. See TypeScript’s explanation of static checking. TypeScript source normally needs processing before it runs as JavaScript.

Static typing does not always need a written annotation

This is TypeScript again, with the annotation removed:

let science = 35;
science = '35';
console.log(science + 5);

The checker can infer that science has type number from its initial value. The later string assignment still produces a diagnostic when checked with tsc --strict --noEmit student-mark.ts.

Inference means deriving type information from the program, not abandoning type checking. Compare this with the earlier JavaScript program: similar-looking source can be handled by different tools with different rules. See TypeScript’s variable annotations and inference.

Typing, reassignment and execution are separate choices

Static versus dynamic concerns how types are treated and checked. let versus const concerns whether a JavaScript name can be reassigned. A const value still has a type, but const is not a substitute for a static type checker.

Compiled versus interpreted concerns how instructions are prepared and carried out. A dynamically typed implementation can compile code, and a statically checked program still needs runtime work. Review compilation and interpretation rather than using these terms interchangeably.

“Strong” and “weak” typing are used inconsistently, often to discuss automatic conversions. Instead of treating them as a quality ranking, ask what a particular operation does with particular values. The next lesson shows JavaScript’s conversions explicitly.

Even a numeric mark can be invalid for the school

This complete JavaScript example stores a numeric science mark of 99. It has type number, but our school marks are out of 50. The comparison science <= 50 asks whether it is at most 50 and produces false.

A broad number type does not establish a valid range, a correct student identifier or truthful input. Static tools can check modeled constraints, but external input and school-specific requirements still need validation. A database response or form value does not become trustworthy just because a type was written beside a variable.

JavaScript · local teaching example

const science = 99;
console.log(typeof science);
console.log(science <= 50);

Expected output

number
false

Fix the assignment without bypassing the checker

The complete TypeScript program below intends to correct science to 40. Identify the mistaken value and replace it without disabling the checker.

let science: number = 35;
science = '40';
console.log(science);

Worked answer

Use the numeric value 40 without quotes. That satisfies the declared number type and gives the intended numeric mark. Changing the type annotation to string would change the data contract rather than fixing this task.

let science: number = 35;
science = 40;
console.log(science);

The corrected source passes tsc --strict --noEmit student-mark.ts. That check prints no mark. When the corrected program is compiled and its emitted JavaScript is run, it prints 40.

Passing a check is useful evidence, not proof of the whole task

JavaScript · a numeric value outside the school’s range

const science = 99;
console.log(typeof science);
console.log(science <= 50);

Expected output

number
false

Static checking can find incompatible assignments and operations in the code it analyzes. It cannot infer every teacher’s intention or make a valid numeric mark belong to the correct student. The number 99 in this example is still a number.

Dynamic languages still distinguish values and enforce rules while running. Some operations reject unsuitable values; others perform conversions. Do not assume JavaScript’s string-plus-number behavior applies to Python or every other dynamic language.

Type checking, input validation and tests against requirements complement each other. Learn to separate these from syntax, runtime and logic errors instead of expecting one tool to catch all mistakes.

Check: what does inference change?

A TypeScript variable begins with let science = 35, without a written annotation. What can the checker do?
Choose one answer. You can try again.

Answer and explanation

Infer number and reject a later incompatible string assignment.

Yes. A static checker can derive the type from the initializer; explicit annotation is not always required.

Check: is a number always a valid mark?

A number-typed variable holds 99, but marks must be between 0 and 50. What is missing?
Choose one answer. You can try again.

Answer and explanation

A check that the numeric value satisfies the school’s allowed range.

Yes. Being numeric and being a valid mark are different requirements.

Use types to catch mismatches, then check the actual requirements

Static checking analyzes types before execution; dynamic languages use the types of actual values during execution. Inference can supply static type information without an explicit annotation.

Typing is different from reassignment rules, compilation and automatic conversion. A successfully checked numeric value can still be wrong for a particular school rule, so validation and tests remain useful.

Explain why the JavaScript example prints 355 while TypeScript can reject its string assignment. Then learn how to convert input deliberately and validate the result.

Reaching the recap and completing the quizzes are separate milestones.

    Next lesson: Type Conversion and Casting: Handle Input Safely →