In TypeScript, type widening and narrowing refer to the automatic adjustment of a variable's type based on its assigned value. Type widening occurs when TypeScript infers a broader type for a variable than its initially declared type, ensuring compatibility with a wider range of values. Type narrowing allows TypeScript to narrow down the type of a variable based on conditions or checks, enabling more precise type information and targeted operations. These mechanisms enhance the language's static type checking capabilities, promoting safer and more reliable code development.
Type widening typically occurs when you declare a variable without explicitly specifying its type, and TypeScript determines the type based on the assigned value.
let num = 5; // Type of 'num' is inferred as numberlet message = "Hello"; // Type of 'message' is inferred as stringconsole.log(num); // Output: 5console.log(message); // Output: Hello
Lines 1–2: We assign values to num
and message
variables. TypeScript widens the types of the num
and message
variables based on their assigned values. The type inference mechanism infers that num
should be of type number
and message
should be of type string
.
Lines 4–5: We print the values of num
and message
variables.
Type narrowing allows us to refine the type of a variable based on certain conditions. We can achieve this using various constructs such as type guards, type assertions, and control flow analysis.
Here's an example of type narrowing using a type guard:
function processValue(value: string | number) {if (typeof value === "string") {// Inside this block, 'value' is narrowed to type 'string'console.log(value.toUpperCase());} else {// Inside this block, 'value' is narrowed to type 'number'console.log(value.toFixed(2));}}processValue("Hello"); // Output: HELLOprocessValue(3.14159); // Output: 3.14
In the above example, the typeof
type guard is used to narrow the type of the value
parameter.
Lines 2–4: If the type of value
is determined to be string
, TypeScript narrows its type to string
inside the corresponding code block.
Lines 5–7: If the type of value
is determined to be number
, TypeScript narrows it to number
inside the else block.
Line 11: We call the processValue()
function and pass a string value.
Line 12: The second call to processValue()
function passes the argument 3.14159
, which is a number. Since the type guard condition evaluates to false
, the code block within the else
statement executes. The number is then formatted with two decimal places using the toFixed()
function, resulting in the output 3.14
.
Free Resources