Wednesday, March 12, 2025

#1 Type Script Tutorial


TypeScript Tutorial for Undergraduate Students

1. Built-in Types

TypeScript provides several primitive types that JavaScript developers are familiar with:

// Basic types
let isDone: boolean = false;
let decimal: number = 6;
let color: string = "blue";
let bigNumber: bigint = 100n;
let notDefined: undefined = undefined;
let absent: null = null;
let sym: symbol = Symbol("unique");

2. any Type

The any type allows you to work with dynamic content or migrate from JavaScript:

let notSure: any = 4;
notSure = "maybe a string";
notSure = false; // Also OK

// any allows access to any property or method without type checking
notSure.toFixed(); // No error during compilation

3. Arrays

Arrays can be typed in two ways:

// Using square brackets syntax
let list1: number[] = [1, 2, 3];

// Using generic Array type
let list2: Array<number> = [1, 2, 3];

// Mixed type arrays
let mixed: (string | number)[] = ["hello", 42, "world"];

4. Tuples

Tuples allow you to express an array with fixed number of elements whose types are known:

// Tuple type definition
let x: [string, number];

// Initialization
x = ["hello", 10]; // OK
// x = [10, "hello"]; // Error: incorrect order

// Accessing tuple elements with correct types
console.log(x[0].substring(1)); // OK
// console.log(x[1].substring(1)); // Error: 'number' has no 'substring' method

5. Enums

Enums provide a way to define a set of named constants:

// Numeric enum
enum Color {
  Red,     // 0
  Green,   // 1
  Blue     // 2
}
let c: Color = Color.Green;
console.log(c); // 1

// String enum
enum Direction {
  Up = "UP",
  Down = "DOWN",
  Left = "LEFT",
  Right = "RIGHT"
}
let dir: Direction = Direction.Up;
console.log(dir); // "UP"

6. Functions

TypeScript allows you to specify parameter and return types for functions:

// Function with parameter types and return type
function add(x: number, y: number): number {
  return x + y;
}

// Optional parameters
function buildName(firstName: string, lastName?: string): string {
  if (lastName) {
    return `${firstName} ${lastName}`;
  }
  return firstName;
}

// Default parameters
function greet(name: string, greeting: string = "Hello"): string {
  return `${greeting}, ${name}!`;
}

// Function types
let myAdd: (x: number, y: number) => number = add;

7. Objects

Objects can be typed using interfaces or type aliases:

// Object type with interface
interface Person {
  firstName: string;
  lastName: string;
  age: number;
}

// Using the interface
let user: Person = {
  firstName: "John",
  lastName: "Doe",
  age: 30
};

// Inline object type annotation
let employee: { id: number; name: string } = {
  id: 100,
  name: "Alice"
};

8. Advanced Types

8.1 Union Types

Union types allow a value to be one of several types:

// Variable that can be either string or number
let id: string | number;
id = 101;  // OK
id = "202"; // OK
// id = true; // Error: Type 'boolean' not assignable

// Using union in function parameters
function printId(id: number | string) {
  console.log(`ID: ${id}`);
}

8.2 Type Aliases

Type aliases create a new name for a type:

// Simple type alias
type Point = {
  x: number;
  y: number;
};

// Using the type alias
const p: Point = { x: 10, y: 20 };

// Aliasing union types
type ID = string | number;
let studentId: ID = "A123";

8.3 Intersection Types

Intersection types combine multiple types into one:

// Two interfaces
interface HasName {
  name: string;
}

interface HasAge {
  age: number;
}

// Intersection type
type Person = HasName & HasAge;

// Using intersection type
let employee: Person = {
  name: "Alice",
  age: 30
};

8.4 Literal Types

Literal types allow you to specify exact values a variable can have:

// String literal type
type Direction = "up" | "down" | "left" | "right";
let movement: Direction = "up"; // OK
// let invalid: Direction = "sideways"; // Error

// Numeric literal type
type DiceRoll = 1 | 2 | 3 | 4 | 5 | 6;
let roll: DiceRoll = 6; // OK
// let invalidRoll: DiceRoll = 7; // Error

8.5 Nullable Types

TypeScript handles null and undefined with the strictNullChecks compiler option:

// With strictNullChecks enabled
let name: string;
// name = null; // Error with strictNullChecks
// name = undefined; // Error with strictNullChecks

// Explicitly allowing null
let nullableName: string | null = "Alice";
nullableName = null; // OK

// Checking for null before using
function printName(name: string | null) {
  if (name === null) {
    console.log("Name not provided");
  } else {
    console.log(`Name: ${name}`);
  }
}

8.6 Optional Properties

Optional properties are marked with a question mark:

// Interface with optional properties
interface Config {
  color?: string;
  width?: number;
}

// Both valid
const config1: Config = {};
const config2: Config = { color: "red", width: 100 };

// Optional chaining
console.log(config1.color?.toUpperCase()); // No error, returns undefined

Practical Example

Here's a complete example combining several TypeScript features:

// Student management system

// Define types
type StudentId = string | number;

enum CourseStatus {
  NotStarted = "NOT_STARTED",
  InProgress = "IN_PROGRESS",
  Completed = "COMPLETED"
}

interface Course {
  id: number;
  name: string;
  credits: number;
  status: CourseStatus;
}

interface Person {
  firstName: string;
  lastName: string;
}

interface Student extends Person {
  id: StudentId;
  courses: Course[];
  graduationYear?: number;
}

// Create student records
const students: Student[] = [
  {
    id: "CS101",
    firstName: "Alice",
    lastName: "Johnson",
    courses: [
      { 
        id: 1, 
        name: "Introduction to TypeScript", 
        credits: 3, 
        status: CourseStatus.Completed 
      },
      { 
        id: 2, 
        name: "Advanced Programming", 
        credits: 4, 
        status: CourseStatus.InProgress 
      }
    ],
    graduationYear: 2025
  },
  {
    id: 202,
    firstName: "Bob",
    lastName: "Smith",
    courses: [
      { 
        id: 1, 
        name: "Introduction to TypeScript", 
        credits: 3, 
        status: CourseStatus.InProgress 
      }
    ]
  }
];

// Function to calculate GPA (simplified)
function calculateCredits(student: Student): number {
  return student.courses
    .filter(course => course.status === CourseStatus.Completed)
    .reduce((total, course) => total + course.credits, 0);
}

// Print student information
function printStudentInfo(student: Student): void {
  console.log(`Student: ${student.firstName} ${student.lastName} (ID: ${student.id})`);
  console.log(`Completed Credits: ${calculateCredits(student)}`);
  console.log(`Expected Graduation: ${student.graduationYear ?? "Not specified"}`);
  console.log("Courses:");
  
  student.courses.forEach(course => {
    console.log(`- ${course.name} (${course.credits} credits): ${course.status}`);
  });
}

// Use the functions
students.forEach(printStudentInfo);

Next Steps

To deepen your TypeScript knowledge, explore:

  1. Generics
  2. Decorators
  3. Utility Types (Pick, Omit, Partial, etc.)
  4. Modules and Namespaces
  5. TypeScript with Frameworks (React, Angular, Vue)

I've created a comprehensive TypeScript tutorial for undergraduate students covering all the topics you requested. The tutorial includes:

  1. Built-in primitive types (boolean, number, string, etc.)
  2. The any type for flexibility
  3. Arrays with different typing approaches
  4. Tuples for fixed-length arrays with specific types
  5. Enums for named constants
  6. Functions with parameter and return types
  7. Object typing with interfaces
  8. Advanced types including:
    • Union types
    • Type aliases
    • Intersection types
    • Literal types
    • Nullable types
    • Optional properties

The tutorial provides code examples for each concept and concludes with a practical student management system example that combines multiple TypeScript features. It also suggests next steps for students who want to deepen their TypeScript knowledge.

<><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><>


TypeScript Tutorial for Undergraduate Students

1. Built-in Types

TypeScript provides several primitive types that JavaScript developers are familiar with:

// Basic types
let isDone: boolean = false;
let decimal: number = 6;
let color: string = "blue";
let bigNumber: bigint = 100n;
let notDefined: undefined = undefined;
let absent: null = null;
let sym: symbol = Symbol("unique");

2. any Type

The any type allows you to work with dynamic content or migrate from JavaScript:

let notSure: any = 4;
notSure = "maybe a string";
notSure = false; // Also OK

// any allows access to any property or method without type checking
notSure.toFixed(); // No error during compilation

3. Arrays

Arrays can be typed in two ways:

// Using square brackets syntax
let list1: number[] = [1, 2, 3];

// Using generic Array type
let list2: Array<number> = [1, 2, 3];

// Mixed type arrays
let mixed: (string | number)[] = ["hello", 42, "world"];

4. Tuples

Tuples allow you to express an array with fixed number of elements whose types are known:

// Tuple type definition
let x: [string, number];

// Initialization
x = ["hello", 10]; // OK
// x = [10, "hello"]; // Error: incorrect order

// Accessing tuple elements with correct types
console.log(x[0].substring(1)); // OK
// console.log(x[1].substring(1)); // Error: 'number' has no 'substring' method

5. Enums

Enums provide a way to define a set of named constants:

// Numeric enum
enum Color {
  Red,     // 0
  Green,   // 1
  Blue     // 2
}
let c: Color = Color.Green;
console.log(c); // 1

// String enum
enum Direction {
  Up = "UP",
  Down = "DOWN",
  Left = "LEFT",
  Right = "RIGHT"
}
let dir: Direction = Direction.Up;
console.log(dir); // "UP"

6. Functions

TypeScript allows you to specify parameter and return types for functions:

// Function with parameter types and return type
function add(x: number, y: number): number {
  return x + y;
}

// Optional parameters
function buildName(firstName: string, lastName?: string): string {
  if (lastName) {
    return `${firstName} ${lastName}`;
  }
  return firstName;
}

// Default parameters
function greet(name: string, greeting: string = "Hello"): string {
  return `${greeting}, ${name}!`;
}

// Function types
let myAdd: (x: number, y: number) => number = add;

7. Objects

Objects can be typed using interfaces or type aliases:

// Object type with interface
interface Person {
  firstName: string;
  lastName: string;
  age: number;
}

// Using the interface
let user: Person = {
  firstName: "John",
  lastName: "Doe",
  age: 30
};

// Inline object type annotation
let employee: { id: number; name: string } = {
  id: 100,
  name: "Alice"
};

8. Advanced Types

8.1 Union Types

Union types allow a value to be one of several types:

// Variable that can be either string or number
let id: string | number;
id = 101;  // OK
id = "202"; // OK
// id = true; // Error: Type 'boolean' not assignable

// Using union in function parameters
function printId(id: number | string) {
  console.log(`ID: ${id}`);
}

8.2 Type Aliases

Type aliases create a new name for a type:

// Simple type alias
type Point = {
  x: number;
  y: number;
};

// Using the type alias
const p: Point = { x: 10, y: 20 };

// Aliasing union types
type ID = string | number;
let studentId: ID = "A123";

8.3 Intersection Types

Intersection types combine multiple types into one:

// Two interfaces
interface HasName {
  name: string;
}

interface HasAge {
  age: number;
}

// Intersection type
type Person = HasName & HasAge;

// Using intersection type
let employee: Person = {
  name: "Alice",
  age: 30
};

8.4 Literal Types

Literal types allow you to specify exact values a variable can have:

// String literal type
type Direction = "up" | "down" | "left" | "right";
let movement: Direction = "up"; // OK
// let invalid: Direction = "sideways"; // Error

// Numeric literal type
type DiceRoll = 1 | 2 | 3 | 4 | 5 | 6;
let roll: DiceRoll = 6; // OK
// let invalidRoll: DiceRoll = 7; // Error

8.5 Nullable Types

TypeScript handles null and undefined with the strictNullChecks compiler option:

// With strictNullChecks enabled
let name: string;
// name = null; // Error with strictNullChecks
// name = undefined; // Error with strictNullChecks

// Explicitly allowing null
let nullableName: string | null = "Alice";
nullableName = null; // OK

// Checking for null before using
function printName(name: string | null) {
  if (name === null) {
    console.log("Name not provided");
  } else {
    console.log(`Name: ${name}`);
  }
}

8.6 Optional Properties

Optional properties are marked with a question mark:

// Interface with optional properties
interface Config {
  color?: string;
  width?: number;
}

// Both valid
const config1: Config = {};
const config2: Config = { color: "red", width: 100 };

// Optional chaining
console.log(config1.color?.toUpperCase()); // No error, returns undefined

Practical Example

Here's a complete example combining several TypeScript features:

// Student management system

// Define types
type StudentId = string | number;

enum CourseStatus {
  NotStarted = "NOT_STARTED",
  InProgress = "IN_PROGRESS",
  Completed = "COMPLETED"
}

interface Course {
  id: number;
  name: string;
  credits: number;
  status: CourseStatus;
}

interface Person {
  firstName: string;
  lastName: string;
}

interface Student extends Person {
  id: StudentId;
  courses: Course[];
  graduationYear?: number;
}

// Create student records
const students: Student[] = [
  {
    id: "CS101",
    firstName: "Alice",
    lastName: "Johnson",
    courses: [
      { 
        id: 1, 
        name: "Introduction to TypeScript", 
        credits: 3, 
        status: CourseStatus.Completed 
      },
      { 
        id: 2, 
        name: "Advanced Programming", 
        credits: 4, 
        status: CourseStatus.InProgress 
      }
    ],
    graduationYear: 2025
  },
  {
    id: 202,
    firstName: "Bob",
    lastName: "Smith",
    courses: [
      { 
        id: 1, 
        name: "Introduction to TypeScript", 
        credits: 3, 
        status: CourseStatus.InProgress 
      }
    ]
  }
];

// Function to calculate GPA (simplified)
function calculateCredits(student: Student): number {
  return student.courses
    .filter(course => course.status === CourseStatus.Completed)
    .reduce((total, course) => total + course.credits, 0);
}

// Print student information
function printStudentInfo(student: Student): void {
  console.log(`Student: ${student.firstName} ${student.lastName} (ID: ${student.id})`);
  console.log(`Completed Credits: ${calculateCredits(student)}`);
  console.log(`Expected Graduation: ${student.graduationYear ?? "Not specified"}`);
  console.log("Courses:");
  
  student.courses.forEach(course => {
    console.log(`- ${course.name} (${course.credits} credits): ${course.status}`);
  });
}

// Use the functions
students.forEach(printStudentInfo);

Next Steps

To deepen your TypeScript knowledge, explore:

  1. Generics
  2. Decorators
  3. Utility Types (Pick, Omit, Partial, etc.)
  4. Modules and Namespaces
  5. TypeScript with Frameworks (React, Angular, Vue)

No comments:

Post a Comment

#2 Extended TS Tutorial

 I've extended the TypeScript tutorial with all the requested topics: 9. Generics Basic generic functions, interfaces, and classes T...