Falytom logoFALYTOM
Games
ToolsUI ComponentsServicesProductsAbout
LoginSign Up
menu
  1. Home
  2. /Web Development
  3. /Typescript
  4. /Primitive Types
Your Progress0%
0 of 30 completed

TypeScript Topics

Getting Started

  • What is TypeScript?
  • TypeScript vs JavaScript
  • Setting Up TypeScript
  • Your First TypeScript Program

Basic Types

  • Primitive Types
  • Arrays and Tuples
  • Objects and Type Aliases
  • Enums
  • Any, Unknown, and Never

Functions & Interfaces

  • Function Types and Signatures
  • Interfaces
  • Optional and Default Parameters
  • Function Overloading

Advanced Types

  • Union and Intersection Types
  • Type Guards and Narrowing
  • Literal Types
  • Type Assertions and Casting

Generics

  • Introduction to Generics
  • Generic Constraints
  • Utility Types

Classes & OOP

  • Classes and Constructors
  • Access Modifiers
  • Inheritance and Polymorphism
  • Abstract Classes and Interfaces

Practical TypeScript

  • Working with Modules
  • TypeScript with React
  • Async/Await and Promises
  • Working with APIs and JSON
  • Type Declarations and DefinitelyTyped
  • TypeScript Best Practices

Primitive Types

Understanding TypeScript's fundamental data types

Primitive types are the fundamental building blocks of TypeScript. They represent simple, immutable values like text, numbers, and true/false values. Understanding these basic types is essential before moving to more complex TypeScript features. Let's explore each primitive type in detail!

What Are Primitive Types?

In TypeScript, primitive types are the most basic data types. Unlike objects or arrays, they represent single values and are immutable (cannot be changed).

TypeScript has seven primitive types:

  • string - Text values
  • number - Numeric values (integers and decimals)
  • boolean - True or false values
  • null - Intentional absence of value
  • undefined - Variable declared but not assigned
  • symbol - Unique identifiers (ES6+)
  • bigint - Large integers (ES2020+)

Note: We'll focus on the first five types as they're used most commonly. Symbol and bigint are advanced features for specific use cases.

String Type

The string type represents textual data. Strings can be created using single quotes, double quotes, or backticks (template literals).

Basic String Usage

string-basics.ts
// String type annotation
let firstName: string = "Yusuf";
let lastName: string = 'Ibrahim';
let city: string = `Lagos`;

// String concatenation
let fullName: string = firstName + " " + lastName;

// Template literals (backticks)
let greeting: string = `Hello, my name is ${firstName} and I live in ${city}`;

// Multiline strings
let address: string = `
  123 Main Street
  Lagos, Africa
  100001
`;

console.log(fullName);     // "Yusuf Ibrahim"
console.log(greeting);     // "Hello, my name is Yusuf and I live in Lagos"

// These would cause errors:
// firstName = 123;        // ❌ Error: number not assignable to string
// lastName = true;        // ❌ Error: boolean not assignable to string

Common String Operations

string-operations.ts
let message: string = "TypeScript is Amazing!";

// Length property
let length: number = message.length;  // 22

// Case conversion
let upper: string = message.toUpperCase();     // "TYPESCRIPT IS AMAZING!"
let lower: string = message.toLowerCase();     // "typescript is amazing!"

// Substring extraction
let sub: string = message.substring(0, 10);    // "TypeScript"
let slice: string = message.slice(0, 10);      // "TypeScript"

// Character access
let firstChar: string = message.charAt(0);     // "T"
let charAtIndex: string = message[0];          // "T" (alternative)

// String search
let index: number = message.indexOf("is");     // 11
let includes: boolean = message.includes("Amazing");  // true

// String splitting
let words: string[] = message.split(" ");      // ["TypeScript", "is", "Amazing!"]

// String replacement
let replaced: string = message.replace("Amazing", "Awesome");

console.log(`Length: ${length}`);
console.log(`Uppercase: ${upper}`);
console.log(`First 10 chars: ${sub}`);

💡 Template Literals Best Practice

Use template literals (backticks) for string interpolation instead of concatenation. They're more readable and prevent common errors:`Hello ${name}` is better than "Hello " + name

Number Type

The number type represents both integers and floating-point numbers. TypeScript uses JavaScript's number type, which is a 64-bit floating-point number.

Basic Number Usage

number-basics.ts
// Integer numbers
let age: number = 25;
let count: number = 100;

// Decimal numbers
let price: number = 99.99;
let temperature: number = 36.5;

// Negative numbers
let debt: number = -1000;
let celsius: number = -5.5;

// Scientific notation
let big: number = 1e6;        // 1,000,000
let small: number = 1e-6;     // 0.000001

// Different number bases
let decimal: number = 100;           // Base 10
let binary: number = 0b1100100;      // Base 2 (binary)
let octal: number = 0o144;           // Base 8 (octal)
let hexadecimal: number = 0x64;      // Base 16 (hexadecimal)

console.log(`Age: ${age}`);
console.log(`Price: ₦${price}`);
console.log(`All represent 100: ${decimal}, ${binary}, ${octal}, ${hexadecimal}`);

// These would cause errors:
// age = "25";          // ❌ Error: string not assignable to number
// price = true;        // ❌ Error: boolean not assignable to number

Mathematical Operations

number-operations.ts
// Basic arithmetic
let a: number = 10;
let b: number = 3;

let sum: number = a + b;           // 13
let difference: number = a - b;    // 7
let product: number = a * b;       // 30
let quotient: number = a / b;      // 3.333...
let remainder: number = a % b;     // 1 (modulo)
let power: number = a ** b;        // 1000 (exponentiation)

// Increment and decrement
let counter: number = 0;
counter++;      // 1
counter--;      // 0
++counter;      // 1
--counter;      // 0

// Math object methods
let absolute: number = Math.abs(-10);           // 10
let rounded: number = Math.round(4.7);          // 5
let ceiling: number = Math.ceil(4.1);           // 5
let floor: number = Math.floor(4.9);            // 4
let maximum: number = Math.max(1, 5, 3);        // 5
let minimum: number = Math.min(1, 5, 3);        // 1
let random: number = Math.random();             // 0 to 1
let squareRoot: number = Math.sqrt(16);         // 4

// Parsing strings to numbers
let parsed1: number = parseInt("123");          // 123
let parsed2: number = parseFloat("123.45");     // 123.45

console.log(`Sum: ${sum}`);
console.log(`Product: ${product}`);
console.log(`Random: ${random}`);

Special Number Values

special-numbers.ts
// Special numeric values
let infinite: number = Infinity;
let negInfinite: number = -Infinity;
let notANumber: number = NaN;  // Not a Number

// Operations producing special values
let divideByZero: number = 10 / 0;              // Infinity
let invalidOperation: number = Math.sqrt(-1);   // NaN
let parseError: number = parseInt("hello");     // NaN

// Checking for special values
let isFiniteValue: boolean = isFinite(100);     // true
let isInfiniteValue: boolean = !isFinite(Infinity);  // true
let isNaNValue: boolean = isNaN(NaN);           // true

console.log(`10 / 0 = ${divideByZero}`);              // Infinity
console.log(`sqrt(-1) = ${invalidOperation}`);        // NaN
console.log(`Is 100 finite? ${isFiniteValue}`);       // true

Watch Out: NaN is technically of type number, but it represents an invalid number operation. Always use isNaN() to check for NaN, don't use === because NaN === NaN is false!

Boolean Type

The boolean type has only two values: true or false. Booleans are primarily used for conditional logic and control flow.

Basic Boolean Usage

boolean-basics.ts
// Boolean type annotation
let isActive: boolean = true;
let isCompleted: boolean = false;
let hasAccess: boolean = true;

// Boolean from comparisons
let isAdult: boolean = 25 >= 18;           // true
let isEqual: boolean = 10 === 10;          // true
let isGreater: boolean = 5 > 10;           // false
let isNotEqual: boolean = 5 !== 10;        // true

// Boolean from logical operations
let both: boolean = true && true;          // true (AND)
let either: boolean = true || false;       // true (OR)
let opposite: boolean = !true;             // false (NOT)

console.log(`Is active: ${isActive}`);
console.log(`Is adult: ${isAdult}`);
console.log(`Both conditions: ${both}`);

// These would cause errors:
// isActive = "true";    // ❌ Error: string not assignable to boolean
// isCompleted = 1;      // ❌ Error: number not assignable to boolean

Boolean in Conditional Statements

boolean-conditions.ts
let age: number = 20;
let hasLicense: boolean = true;
let hasInsurance: boolean = true;

// If statements
if (age >= 18) {
  console.log("You are an adult");
}

// If-else
if (hasLicense) {
  console.log("You can drive");
} else {
  console.log("You cannot drive");
}

// If-else if-else
if (age < 18) {
  console.log("Minor");
} else if (age < 65) {
  console.log("Adult");
} else {
  console.log("Senior");
}

// Logical operators with booleans
let canDrive: boolean = age >= 18 && hasLicense;
let canDriveLegally: boolean = canDrive && hasInsurance;

if (canDriveLegally) {
  console.log("You can legally drive");
}

// Ternary operator
let status: string = isActive ? "Active" : "Inactive";
let access: string = hasAccess ? "Granted" : "Denied";

console.log(`Status: ${status}`);
console.log(`Access: ${access}`);

Truthy and Falsy Values

truthy-falsy.ts
// TypeScript inherits JavaScript's truthy/falsy behavior

// Falsy values (convert to false)
let falsyValues = [
  false,
  0,
  -0,
  0n,
  "",           // empty string
  null,
  undefined,
  NaN
];

// Truthy values (everything else converts to true)
let truthyValues = [
  true,
  1,
  -1,
  "0",          // string "0" is truthy!
  "false",      // string "false" is truthy!
  [],           // empty array is truthy
  {},           // empty object is truthy
  42,
  "hello"
];

// Using in conditionals
let value: string = "hello";

if (value) {  // Checks if value is truthy
  console.log("Value exists and is truthy");
}

// Boolean conversion
let explicit1: boolean = Boolean(0);           // false
let explicit2: boolean = Boolean("hello");     // true
let explicit3: boolean = !!"hello";            // true (double negation)

// Type-safe approach: explicit comparison
let count: number = 0;

// ❌ Less clear (relying on truthy/falsy)
if (count) {
  console.log("Count exists");
}

// ✅ Better: explicit comparison
if (count > 0) {
  console.log("Count is positive");
}

⚠️ Boolean Best Practice

While TypeScript allows relying on truthy/falsy values, it's often clearer to use explicit comparisons. Instead of if (value), use if (value !== null) or if (value.length > 0) for better clarity.

Null and Undefined

null and undefined represent absence of value, but with subtle differences:

  • null: Intentional absence of value (explicitly assigned)
  • undefined: Variable declared but not yet assigned a value

Understanding Null

null-example.ts
// null represents intentional "no value"
let selectedUser: string | null = null;  // Explicitly no user selected

// Later, user is selected
selectedUser = "Yusuf Ibrahim";

// Later, user is deselected
selectedUser = null;

// Function that might return null
function findUser(id: number): string | null {
  if (id === 1) {
    return "Admin User";
  }
  return null;  // User not found
}

const user1 = findUser(1);   // "Admin User"
const user2 = findUser(999); // null

// Checking for null
if (user2 === null) {
  console.log("User not found");
}

console.log(`Selected user: ${selectedUser}`);

Understanding Undefined

undefined-example.ts
// undefined represents "not yet assigned"
let name: string | undefined;

console.log(name);  // undefined (declared but not assigned)

// Later assigned
name = "Yusuf";

// Function without return value
function logMessage(msg: string): void {
  console.log(msg);
  // No return statement = returns undefined
}

const result = logMessage("Hello");  // result is undefined

// Optional parameters are undefined if not provided
function greet(name: string, title?: string): string {
  if (title === undefined) {
    return `Hello, ${name}`;
  }
  return `Hello, ${title} ${name}`;
}

console.log(greet("Yusuf"));              // title is undefined
console.log(greet("Yusuf", "Dr."));       // title is "Dr."

Null vs Undefined in Practice

null-vs-undefined.ts
// When to use null vs undefined

// ✅ Use undefined for:
// 1. Optional parameters/properties
interface User {
  name: string;
  nickname?: string;  // undefined if not provided
}

// 2. Function parameters not provided
function process(data: string, options?: object) {
  console.log(options);  // undefined if not passed
}

// ✅ Use null for:
// 1. Intentionally empty/reset values
let currentDocument: Document | null = null;  // No document loaded

// 2. API responses indicating "no data"
interface ApiResponse {
  data: string | null;  // null = no data available
}

// 3. Database queries returning no results
function getUserById(id: number): User | null {
  // Return null if user doesn't exist
  return null;
}

// Checking for both
let value: string | null | undefined;

// Check for null specifically
if (value === null) {
  console.log("Value is null");
}

// Check for undefined specifically
if (value === undefined) {
  console.log("Value is undefined");
}

// Check for either (nullish)
if (value == null) {  // == checks both null and undefined
  console.log("Value is null or undefined");
}

// Better: use ?? nullish coalescing
let displayName = value ?? "Guest";  // Use "Guest" if value is null or undefined

Common TypeScript Error

Code with Error
// Attempting to use null/undefined without proper handling
let userName: string = null;  // Error with strict null checks

function getLength(text: string): number {
  return text.length;
}

const result = getLength(null);  // Runtime error in JavaScript!

❌ Type 'null' is not assignable to type 'string' (with strictNullChecks enabled)

What's Wrong?

TypeScript's strict null checks prevent you from assigning null or undefined to variables unless you explicitly allow it. This catches potential runtime errors!

Corrected Code
// Properly handle null/undefined with union types
let userName: string | null = null;  // ✅ Now it's allowed

function getLength(text: string | null): number {
  if (text === null) {
    return 0;  // Handle null case
  }
  return text.length;  // TypeScript knows text is string here
}

const result1 = getLength("Hello");  // 5
const result2 = getLength(null);     // 0

Solution: Use union types to explicitly allow null or undefined

Strict Null Checks

tsconfig.json
{
  "compilerOptions": {
    // This prevents assigning null/undefined to other types
    "strictNullChecks": true,
    
    // Or enable all strict checks (includes strictNullChecks)
    "strict": true
  }
}

Best Practice: Always enable strictNullChecks (or strict mode) in tsconfig.json. This forces you to explicitly handle null and undefined, preventing countless runtime errors!

Type Annotations vs Type Inference

TypeScript can often figure out types automatically, but sometimes you need to specify them explicitly:

annotations-vs-inference.ts
// Type Inference - TypeScript figures it out
let inferredString = "Hello";      // Type: string (inferred)
let inferredNumber = 42;           // Type: number (inferred)
let inferredBoolean = true;        // Type: boolean (inferred)

// Type Annotations - You specify explicitly
let annotatedString: string = "Hello";
let annotatedNumber: number = 42;
let annotatedBoolean: boolean = true;

// When inference is enough
let message = "TypeScript";        // Inferred as string
message = "is awesome";            // ✅ Works
// message = 123;                  // ❌ Error: number not assignable to string

// When you need annotations
let value: string | number;        // Must annotate union type
value = "text";                    // ✅ Works
value = 123;                       // ✅ Works

// Function parameters always need annotations
function greet(name: string) {     // Must annotate parameter
  return `Hello, ${name}`;       // Return type inferred as string
}

// Function return type can be inferred or annotated
function add(a: number, b: number) {
  return a + b;  // Return type inferred as number
}

// Explicit return type (recommended for functions)
function multiply(a: number, b: number): number {
  return a * b;
}

💡 When to Use Annotations

  • Always: Function parameters and return types
  • Usually: Object properties in interfaces/types
  • Sometimes: Variables when type can't be inferred
  • Rarely: Simple variable assignments (let TypeScript infer)

Test Your Knowledge

Let's check your understanding of primitive types:

Type Safety Check

Which variable declaration has a type error?

let name: string = "Yusuf";
let age: number = 25;
let isActive: boolean = true;
let score: number = "100";

Practical Example: User Profile

Let's combine all primitive types in a practical example:

user-profile.ts
// User profile using primitive types

// User data
let userId: number = 12345;
let userName: string = "Yusuf Ibrahim";
let userEmail: string = "yusuf@example.com";
let userAge: number = 25;
let isVerified: boolean = true;
let isPremium: boolean = false;
let lastLogin: string | null = null;  // Not logged in yet
let phoneNumber: string | undefined;  // Not provided

// Account balance
let balance: number = 50000.50;
let currency: string = "NGN";

// User preferences
let theme: string = "dark";
let notifications: boolean = true;
let language: string = "en";

// Function to display user info
function displayUserInfo(): void {
  console.log("=== User Profile ===");
  console.log(`ID: ${userId}`);
  console.log(`Name: ${userName}`);
  console.log(`Email: ${userEmail}`);
  console.log(`Age: ${userAge}`);
  console.log(`Verified: ${isVerified ? "Yes" : "No"}`);
  console.log(`Premium: ${isPremium ? "Yes" : "No"}`);
  console.log(`Balance: ${currency} ${balance.toFixed(2)}`);
  
  if (lastLogin !== null) {
    console.log(`Last Login: ${lastLogin}`);
  } else {
    console.log("Last Login: Never");
  }
  
  if (phoneNumber !== undefined) {
    console.log(`Phone: ${phoneNumber}`);
  }
}

// Function to update balance
function updateBalance(amount: number, operation: string): void {
  if (operation === "add") {
    balance = balance + amount;
  } else if (operation === "subtract") {
    balance = balance - amount;
  }
}

// Function to check eligibility for premium
function canUpgradeToPremium(): boolean {
  return isVerified && balance >= 10000;
}

// Update user data
lastLogin = "2024-12-25T10:30:00";
phoneNumber = "+234-803-123-4567";

// Perform operations
displayUserInfo();
updateBalance(5000, "add");

const eligible: boolean = canUpgradeToPremium();
console.log(`Eligible for Premium: ${eligible ? "Yes" : "No"}`);
console.log(`New Balance: ${currency} ${balance.toFixed(2)}`);

Common Mistakes with Primitive Types

Mistake 1: String Number Confusion

mistake-1.ts
// ❌ Common mistake
let age: number = "25";  // Error: string not assignable to number

// ✅ Correct approaches
let age1: number = 25;                    // Number literal
let age2: number = parseInt("25");        // Parse string to number
let age3: number = Number("25");          // Convert string to number

// Be careful with user input
let userInput: string = "25";
let userAge: number = parseInt(userInput);  // Always parse/convert

Mistake 2: Boolean String Confusion

mistake-2.ts
// ❌ Common mistake
let isActive: boolean = "true";  // Error: string not assignable to boolean

// ✅ Correct approaches
let isActive1: boolean = true;                        // Boolean literal
let isActive2: boolean = userInput === "true";        // Comparison
let isActive3: boolean = Boolean(userInput);          // Convert (be careful!)

// Watch out: all non-empty strings are truthy
Boolean("false");  // true! (the string "false" is truthy)

Mistake 3: Null/Undefined Not Handled

mistake-3.ts
// ❌ Unsafe (crashes if value is null)
function getLength(text: string | null): number {
  return text.length;  // Error if text is null
}

// ✅ Safe: Check before using
function getLengthSafe(text: string | null): number {
  if (text === null) {
    return 0;
  }
  return text.length;  // TypeScript knows text is string here
}

// ✅ Safe: Use optional chaining
function getLengthOptional(text: string | null): number {
  return text?.length ?? 0;  // Returns 0 if text is null
}

Mistake 4: Type Coercion Confusion

mistake-4.ts
// JavaScript's type coercion can be confusing
let num: number = 5;
let str: string = "10";

// ❌ Unexpected behavior in JavaScript
console.log(num + str);     // "510" (string concatenation, not addition!)

// ✅ TypeScript can't prevent this, but be explicit
let sum: number = num + parseInt(str);     // 15 (correct addition)
let concat: string = num.toString() + str; // "510" (intentional)

Best Practices for Primitive Types

  1. Always enable strict mode in tsconfig.json for better type safety
  2. Use explicit type annotations for function parameters and return types
  3. Let TypeScript infer types for simple variable assignments
  4. Handle null/undefined explicitly with type guards or optional chaining
  5. Use template literals instead of string concatenation
  6. Be explicit with comparisons rather than relying on truthy/falsy
  7. Parse user input to correct types before use
  8. Use const for values that won't change, let for values that will
best-practices.ts
// ✅ Good practices example
function calculateDiscount(
  price: number,
  discountPercent: number,
  isPremiumMember: boolean
): number {
  // Explicit parameter types and return type
  
  if (discountPercent < 0 || discountPercent > 100) {
    throw new Error("Invalid discount percentage");
  }
  
  let discount: number = price * (discountPercent / 100);
  
  // Explicit boolean comparison
  if (isPremiumMember === true) {
    discount = discount * 1.1;  // Extra 10% for premium
  }
  
  return price - discount;
}

// Use the function
const originalPrice: number = 10000;
const discountAmount: number = 15;
const isPremium: boolean = true;

const finalPrice = calculateDiscount(originalPrice, discountAmount, isPremium);
console.log(`Final price: ₦${finalPrice.toFixed(2)}`);

Key Takeaways

  • string, number, and boolean are the most commonly used primitive types
  • null represents intentional absence of value
  • undefined represents uninitialized variables
  • Always enable strictNullChecks to prevent null/undefined errors
  • Type annotations use syntax: variable: type = value
  • TypeScript can infer types but explicit annotations are clearer for functions
  • Template literals (`) are better than string concatenation
  • Handle null/undefined explicitly with type guards or optional chaining
  • Use === for comparisons, not ==
  • Parse user input to correct types before using

What's Next?

Now that you understand primitive types, you're ready to explore Arrays and Tuples! In the next lesson, you'll learn how to work with collections of data, create type-safe arrays, and use tuples for fixed-length, ordered data. These concepts build directly on the primitive types you just mastered.

Get ready to handle multiple values and structured data with TypeScript!

Mastering TypeScript primitive types! Check this out!

Previous
Your First TypeScript Program
Next
Arrays and Tuples

Never Miss a New TypeScript Tutorial

Join 1,000+ developers learning TypeScript step-by-step. Get new tutorials, type safety tips, and exclusive resources delivered to your inbox - completely FREE.

You might also like

UI Components

Ready-made components for your projects

Developer Tools

Boost productivity with handy generators

HTML Game

Learn HTML concepts through interactive gameplay

Join Our Web Development Training Program

Master frontend & backend development with hands-on projects.

TypeScript Tutorials

0 of 30 completed

Your Progress0%

Topics

Getting Started

  • What is TypeScript?
  • TypeScript vs JavaScript
  • Setting Up TypeScript
  • Your First TypeScript Program

Basic Types

  • Primitive Types
  • Arrays and Tuples
  • Objects and Type Aliases
  • Enums
  • Any, Unknown, and Never

Functions & Interfaces

  • Function Types and Signatures
  • Interfaces
  • Optional and Default Parameters
  • Function Overloading

Advanced Types

  • Union and Intersection Types
  • Type Guards and Narrowing
  • Literal Types
  • Type Assertions and Casting

Generics

  • Introduction to Generics
  • Generic Constraints
  • Utility Types

Classes & OOP

  • Classes and Constructors
  • Access Modifiers
  • Inheritance and Polymorphism
  • Abstract Classes and Interfaces

Practical TypeScript

  • Working with Modules
  • TypeScript with React
  • Async/Await and Promises
  • Working with APIs and JSON
  • Type Declarations and DefinitelyTyped
  • TypeScript Best Practices
Falytom logoFALYTOM

Learn technologies like HTML, CSS, JavaScript, React, NodeJS and more through interactive games, tutorials, components and free tools. Transform your businesses with AI chatbots, SEO-optimized websites, and professional development services.

© 2025 Tomilola Group
  • Facebook logo
  • Twitter logo
  • Instagram logo
  • LinkedIn logo
  • GitHub logo
  • YouTube logo