TypeScript Basic Types: Primitive, Special, Interfaces, Arrays & Tuples

1. What are the primitive types in TypeScript?

Primitive types are the basic building blocks for data in TypeScript, inherited from JavaScript.

Use Case: Declaring variables with simple, predictable data types.

Note: TypeScript enforces type checking at compile time, unlike JavaScript.

Can you give an example of primitive types?


// Primitive types: number, string, boolean
let age: number = 25;
let name: string = "kristal";
let isActive: boolean = true;

console.log(`Name: ${name}, Age: ${age}, Active: ${isActive}`);

// Type errors (uncomment to see errors)
// age = "30"; // Error: Type 'string' is not assignable to type 'number'
// isActive = 1; // Error: Type 'number' is not assignable to type 'boolean'
    

Output (when compiled to JavaScript and run):


Name: kristal, Age: 25, Active: true
    

2. What are the special types in TypeScript?

Use Case: Handling edge cases, dynamic data, or function return types.

Can you give an example of special types?


// Special types
let anyValue: any = 42;
anyValue = "hello"; // No error

let unknownValue: unknown = 42;
// console.log(unknownValue.length); // Error: 'length' does not exist on type 'unknown'
if (typeof unknownValue === "string") {
  console.log(unknownValue.length); // Safe after type check
}

function logMessage(): void {
  console.log("No return value");
}

let nullValue: null = null;
let undefinedValue: undefined = undefined;

function throwError(message: string): never {
  throw new Error(message);
}

// Example usage
logMessage();
console.log(`Any: ${anyValue}, Null: ${nullValue}, Undefined: ${undefinedValue}`);

// Never example (uncomment to see error handling)
// throwError("Test error");
    

Output (when compiled and run):


No return value
Any: hello, Null: null, Undefined: undefined
    

3. What are type annotations and interfaces in TypeScript?

Type Annotations: Explicitly specify a variable’s type using : Type.

Interfaces: Define the structure of objects, specifying property types and optional methods.

Use Case: Ensuring consistent object shapes and type safety in functions or classes.

Can you give an example of type annotations and interfaces?


// Type annotations and interfaces
interface Employee {
  name: string;
  id: number;
  salary?: number; // Optional property
  getDetails(): string;
}

// Type annotation with interface
let employee: Employee = {
  name: "Sashi",
  id: 101,
  getDetails() {
    return `${this.name} (ID: ${this.id})`;
  }
};

// Function with interface
function printEmployee(emp: Employee): void {
  console.log(emp.getDetails());
  if (emp.salary) {
    console.log(`Salary: $${emp.salary}`);
  }
}

// Usage
printEmployee(employee);
employee.salary = 60000;
printEmployee(employee);
    

Output:


Sashi (ID: 101)
Sashi (ID: 101)
Salary: $60000
    

4. What are arrays and tuples in TypeScript?

Arrays: Ordered collections of elements of the same type.

Tuples: Fixed-length arrays with specific types for each position.

Use Case: Arrays for homogeneous data; tuples for fixed, heterogeneous data.

Can you give an example of arrays and tuples?


// Arrays and tuples
let numbers: number[] = [1, 2, 3, 4];
let names: Array<string> = ["kristal", "Sashi"];

// Array operations
numbers.push(5);
console.log(`Numbers: ${numbers}`);

// Tuple
let person: [string, number, boolean] = ["hari", 30, true];

// Tuple access
console.log(`Person: Name=${person[0]}, Age=${person[1]}, Active=${person[2]}`);

// Type error (uncomment to see)
// person[0] = 123; // Error: Type 'number' is not assignable to type 'string'
    

Output:


Numbers: 1,2,3,4,5
Person: Name=hari, Age=30, Active=true
    

5. Can you provide a comprehensive example of TypeScript basic types?

Project Structure:


ts-types-example/
├── src/
│   └── main.ts
├── tsconfig.json
└── package.json
    

main.ts:


// Comprehensive example of TypeScript basic types
interface User {
  id: number;
  name: string;
  scores: number[];
  profile: [string, number]; // [department, years]
  logInfo?(): void;
}

// Function with type annotations and special types
function processUser(user: User, defaultStatus: string = "active"): string | never {
  if (!user.name) {
    throw new Error("Name is required");
  }

  let status: any = defaultStatus; // Flexible but unsafe
  let unknownData: unknown = user.scores;

  // Type narrowing for unknown
  if (Array.isArray(unknownData)) {
    const avgScore: number = unknownData.reduce((a, b) => a + b, 0) / unknownData.length;
    return `${user.name} (ID: ${user.id}), Dept: ${user.profile[0]}, Years: ${user.profile[1]}, Avg Score: ${avgScore}, Status: ${status}`;
  }
  return "Invalid data";
}

// Example usage
const user: User = {
  id: 101,
  name: "kristal",
  scores: [85, 90, 95],
  profile: ["Engineering", 5],
  logInfo() {
    console.log(`Logging: ${this.name}`);
  }
};

try {
  console.log(processUser(user));
  user.logInfo();

  // Using null/undefined
  let temp: null = null;
  let unassigned: undefined = undefined;
  console.log(`Temp: ${temp}, Unassigned: ${unassigned}`);
} catch (error: unknown) {
  console.log(`Error: ${(error as Error).message}`);
}
    

package.json:


{
  "name": "ts-types-example",
  "version": "1.0.0",
  "scripts": {
    "start": "tsc && node dist/main.js",
    "build": "tsc",
    "watch": "tsc --watch"
  },
  "devDependencies": {
    "typescript": "^5.6.2"
  }
}
    

tsconfig.json:


{
  "compilerOptions": {
    "target": "ES2020",
    "module": "NodeNext",
    "outDir": "./dist",
    "rootDir": "./src",
    "strict": true,
    "esModuleInterop": true,
    "skipLibCheck": true
  },
  "include": ["src/**/*"],
  "exclude": ["node_modules"]
}
    

Steps to Run:

  1. Create the project structure.
  2. Install dependencies: npm install.
  3. Compile: npm run build.
  4. Run: npm start.

Output:


kristal (ID: 101), Dept: Engineering, Years: 5, Avg Score: 90, Status: active
Logging: kristal
Temp: null, Unassigned: undefined
    

Description:

6. What are common mistakes in TypeScript basic types?

7. What are best practices for TypeScript basic types?

  1. Primitive Types:
    • Always specify types (e.g., : number) to avoid implicit any.
    • Use const assertions for literals (e.g., as const).
  2. Special Types:
    • Prefer unknown over any for safer dynamic typing.
    • Use void for functions with no return value.
    • Reserve never for exhaustive checks or error-throwing functions.
  3. Type Annotations/Interfaces:
    • Define interfaces for complex object shapes.
    • Use optional properties and readonly modifiers where needed.
  4. Arrays/Tuples:
    • Use Type[] for arrays; [Type1, Type2] for tuples.
    • Validate tuple lengths and types strictly.
  5. General:
    • Enable strict mode in tsconfig.json for maximum type safety.
    • Use type narrowing (e.g., typeof, instanceof) for unknown.
    • Document interfaces with comments for clarity.
    • Test with edge cases (e.g., null, undefined, invalid types).
    • Use tsc --noEmit to check types without generating JavaScript.