TypeScript - Variables
TypeScript - Variables (let/const)
Section titled “TypeScript - Variables (let/const)”Variables are fundamental elements in programming used to store and manage data. They act as named containers for values that your program can manipulate. In TypeScript, as in modern JavaScript (ES6+), variables are primarily declared using the let and const keywords.
TypeScript variable names must follow JavaScript naming rules:
- Names can contain letters, digits, underscores (
_), and dollar signs ($). - Names must begin with a letter, underscore (
_), or dollar sign ($). They cannot start with a digit. - Names are case-sensitive (
myVarandmyvarare different). - Reserved keywords (like
let,const,class,function, etc.) cannot be used as variable names. - Names cannot contain spaces.
Variables must be declared before they are used.
Declaring Variables with let and const
Section titled “Declaring Variables with let and const”Modern TypeScript (and JavaScript) heavily favors let and const over the older var keyword due to their improved scoping rules (block scope) and behavior.
const: Used for variables whose value will not be reassigned after initialization. It creates an immutable binding, not an immutable value (e.g., you can modify properties of aconstobject, but not assign a new object to the variable). Preferconstby default.let: Used for variables whose value may be reassigned later.letallows you to change the value held by the variable.
Both let and const introduce block scoping. A variable declared with let or const is only accessible within the block (enclosed by {}) where it is defined.
Type Annotations
Section titled “Type Annotations”TypeScript allows (and encourages) explicit type annotations for variables using a colon (:) followed by the type name after the variable name.
let age: number = 30;const pi: number = 3.14159;let username: string = "Alice";const isActive: boolean = true;
let anything: any; // Avoid 'any' if possiblelet unknownValue: unknown; // Safer alternative to 'any'
// Reassigning 'let' variable is allowedage = 31;username = 'Bob';
// Reassigning 'const' variable is NOT allowed// pi = 3.14; // Error: Cannot assign to 'pi' because it is a constant.// isActive = false; // ErrorType Inference
Section titled “Type Inference”If you initialize a variable with a value but don’t provide an explicit type annotation, TypeScript will often infer the type based on the initial value. This can make code more concise.
let inferredAge = 30; // TypeScript infers 'number'const inferredUsername = "Alice"; // TypeScript infers 'string'
// inferredAge = "thirty"; // Error: Type 'string' is not assignable to type 'number'.While type inference is powerful, explicitly annotating types (especially for function parameters/return types and complex object structures) improves code clarity and helps prevent subtle bugs.
Variable Declaration Options
Section titled “Variable Declaration Options”| Syntax | Description |
|---|---|
const name: string = "mary"; | Declare a constant variable with an explicit type and initial value. Type cannot change, value cannot be reassigned. |
let score: number; | Declare a variable with an explicit type but no initial value. Its value is undefined until assigned. Can be reassigned later with values of the specified type (number). |
const city = "London"; | Declare a constant variable with an initial value. TypeScript infers the type (string). Value cannot be reassigned. |
let count; | Declare a variable without type or initial value. TypeScript infers the type as any. Its value is undefined. Can be reassigned with any type (generally discouraged). |
Example: Variables in TypeScript
Section titled “Example: Variables in TypeScript”const studentName: string = "John Doe";let score1: number = 85;let score2: number = 92.5;let totalScore = score1 + score2; // Inferred type: number
console.log(`Name: ${studentName}`);console.log(`First score: ${score1}`);console.log(`Second score: ${score2}`);console.log(`Total score: ${totalScore}`);
score1 = 88; // Allowed because score1 is declared with 'let'console.log(`Updated first score: ${score1}`);
// studentName = "Jane Doe"; // Error: Cannot assign to 'studentName' because it is a constant.Type Assertion
Section titled “Type Assertion”Sometimes, you might have more specific information about a variable’s type than TypeScript does (especially when dealing with values of type any or unknown, or interacting with external JavaScript). Type Assertion allows you to tell the compiler to treat a variable as a specific type. It’s purely a compile-time construct and has no runtime effect; it doesn’t perform any conversion or checking at runtime.
There are two syntaxes:
- Angle-bracket syntax:
<Type>value assyntax:value as Type(Preferred, especially in JSX/TSX files where angle brackets conflict with HTML/XML syntax).
Use type assertions cautiously, only when you are certain about the type, as they bypass standard type checking.
Example: Type Assertion
Section titled “Example: Type Assertion”let someValue: unknown = "this is a string";
// We know it's a string, but TypeScript only knows it's 'unknown'.// We need to assert the type to use string methods.
// Using 'as' syntax (preferred):let strLength: number = (someValue as string).length;console.log(`String length (using 'as'): ${strLength}`);
// Using angle-bracket syntax:let strLength2: number = (<string>someValue).length;console.log(`String length (using '<>'): ${strLength2}`);
// Incorrect assertion can lead to runtime errors:let problematicValue: any = 123;// const len = (problematicValue as string).length; // Compiles, but will likely cause a runtime error!// console.log(len); // TypeError: problematicValue.length is not a functionVariable Scope
Section titled “Variable Scope”Scope determines the accessibility of variables within your code. TypeScript, leveraging let and const, primarily uses:
- Global Scope: Variables declared outside any function or block. In modules, top-level variables are scoped to the module, not truly global unless attached explicitly to the global object (e.g.,
windowin browsers, discouraged). - Module Scope: Variables declared at the top level of a module file (
.tsfile withimportorexport) are accessible only within that module, unless exported. - Function Scope: Variables declared inside a function are typically accessible only within that function (applies also to
var). - Block Scope: Variables declared with
letorconstinside a block (e.g.,if,for,{}) are only accessible within that specific block.
Example: Variable Scope
Section titled “Example: Variable Scope”// Module Scope (if this is in a module file)const moduleVar: string = "I am module-scoped";
function testScope(condition: boolean): void { // Function Scope const functionVar: string = "I am function-scoped"; console.log(moduleVar); // Accessible
if (condition) { // Block Scope let blockVar: string = "I am block-scoped"; const anotherBlockVar: number = 10; console.log(functionVar); // Accessible console.log(blockVar); // Accessible }
// console.log(blockVar); // Error: Cannot find name 'blockVar'. (Outside its block)}
testScope(true);// console.log(functionVar); // Error: Cannot find name 'functionVar'. (Outside its function)Understanding block scope with let and const is crucial for preventing common errors associated with the older var keyword’s function scoping and hoisting behavior.