Top 35+ TypeScript Interview Questions and Answers with detailed explanation

TypeScript is a powerful superset of JavaScript that adds static typing and other features to improve code quality and maintainability. Here are over 35+ interview questions commonly asked in TypeScript interview along with detailed answers.

TypeScript Interview Questions and Answers with detailed explanation
TypeScript Interview Questions and Answers

TypeScript Interview Questions and Answers with detailed explanation

  1. What is TypeScript, and how does it differ from JavaScript?
  2. What are the built-in types in TypeScript?
  3. How do you declare variables in TypeScript?
  4. What are access modifiers in TypeScript?
  5. What is an interface in TypeScript?
  6. Explain generics in TypeScript.
  7. What is the purpose of the tsconfig.json file?
  8. How does TypeScript handle null and undefined?
  9. What are decorators in TypeScript?
  10. Can you explain what type inference is in TypeScript?
  11. What is conditional typing in TypeScript?
  12. How do you create an immutable object in TypeScript?
  13. Explain how modules work in TypeScript.
  14. How do you handle asynchronous programming in TypeScript?
  15. What are tuples in TypeScript?
  16. Explain how error handling works in TypeScript?
  17. What is template literal syntax in TypeScript?
  18. How do you convert between different data types in TypeScript?
  19. What are mixins in TypeScript?
  20. How do you handle default parameters in functions?
  21. What are Type Aliases in TypeScript, and how are they used?
  22. What is the unknown type in TypeScript, and how does it differ from any?
  23. How do Mapped Types work in TypeScript?
  24. What is Type Assertion in TypeScript, and how is it different from Type Casting?
  25. What is the never type, and when is it used in TypeScript?
  26. Explain Union and Intersection Types in TypeScript.
  27. How does TypeScript handle Type Narrowing?
  28. What is typeof Type Guards in TypeScript?
  29. Explain the purpose of keyof operator in TypeScript.
  30. How do Conditional Types work in TypeScript?
  31. What are Utility Types in TypeScript?
  32. Explain the concept of Index Signatures in TypeScript.
  33. What is Type Compatibility in TypeScript?
  34. How does non-null assertion (!) operator work?
  35. What is Discriminated Union in TypeScript?
  36. How does as const work in TypeScript?
  37. What is the difference between type and interface?
  38. Explain the concept of Optional Chaining in TypeScript.

1. What is TypeScript, and how does it differ from JavaScript?

Answer:

TypeScript is an open-source programming language developed by Microsoft that builds on JavaScript by adding static type definitions. While JavaScript is dynamically typed, meaning types are determined at runtime, TypeScript allows developers to specify types at compile time, which helps catch errors early in the development process.

Key differences include:

  • Static vs. Dynamic Typing: TypeScript uses static typing, which means types are checked at compile time. JavaScript uses dynamic typing, where types are checked at runtime.
  • Type Annotations: In TypeScript, you can annotate variables and function parameters with specific types (e.g., number, string), enhancing code readability and maintainability.
  • Advanced Features: TypeScript includes features like interfaces, enums, generics, and decorators that are not available in JavaScript.
  • Compilation: TypeScript needs to be compiled into JavaScript before it can run in a browser or Node.js environment.

2. What are the built-in types in TypeScript?

Answer:

TypeScript provides several built-in types that can be used to define the type of a variable. Some of the most common built-in types include:

  • any: Represents any type of value; useful for variables that can hold multiple types.
  • boolean: Represents a true/false value.
  • number: Represents both integer and floating-point numbers.
  • string: Represents textual data.
  • void: Indicates that a function does not return a value.
  • null and undefined: Represent absence of value or uninitialized variables.
  • object: Represents non-primitive types (i.e., anything that is not a primitive type).

By using these built-in types, developers can ensure more robust type checking and better code clarity.

3. How do you declare variables in TypeScript?

Answer: In TypeScript, you can declare variables using three keywords: let, const, and var.

  • let: Used to declare block-scoped variables.
  let age: number = 30;
  • const: Used to declare block-scoped constants that cannot be reassigned.
  const pi: number = 3.14;
  • var: Declares function-scoped or globally-scoped variables but is generally discouraged due to its hoisting behavior.
  var name: string = "John";

Using let and const is preferred for better scoping rules.

4. What are access modifiers in TypeScript?

Answer:

Access modifiers control the visibility of class members (properties and methods). TypeScript supports three access modifiers:

  • public: Members are accessible from anywhere (default modifier).
  class Person {
      public name: string;
      constructor(name: string) {
          this.name = name;
      }
  }
  • private: Members are accessible only within the class they are declared.
  class Person {
      private age: number;
      constructor(age: number) {
          this.age = age;
      }
  }
  • protected: Members are accessible within the class and by derived classes.
  class Animal {
      protected species: string;
      constructor(species: string) {
          this.species = species;
      }
  }

  class Dog extends Animal {
      constructor() {
          super("Dog");
      }
  }

These modifiers enhance encapsulation and help manage access to class members effectively.

5. What is an interface in TypeScript?

Answer:

An interface in TypeScript defines a contract for classes or objects. It specifies the structure that an object should adhere to without implementing any functionality. Interfaces can include properties, methods, and index signatures.

Example:

interface Person {
    name: string;
    age: number;
    greet(): void;
}

class Employee implements Person {
    constructor(public name: string, public age: number) {}

    greet() {
        console.log(`Hello, my name is ${this.name}`);
    }
}

In this example, the Person interface defines a structure that the Employee class must implement. This promotes code consistency and helps with type-checking.

6. Explain generics in TypeScript.

Generics allow developers to create reusable components or functions that work with any data type while maintaining type safety. They enable you to define a component or function with a placeholder for the type that will be specified later.

Example:

function identity<T>(arg: T): T {
    return arg;
}

let output = identity<string>("Hello World");

In this example, T acts as a placeholder for any type passed to the function identity. This allows for greater flexibility while still enforcing type safety.

7. What is the purpose of the tsconfig.json file?

Answer:

The tsconfig.json file is a configuration file used by the TypeScript compiler (tsc) to specify compiler options and project settings. It defines how the TypeScript files should be compiled into JavaScript.

Key properties you might find in tsconfig.json include:

  • compilerOptions: Specifies various options such as target ECMAScript version (es5, es6, etc.), module system (commonjs, esnext, etc.), strictness settings, and more.
  • include/exclude: Defines which files or directories should be included or excluded during compilation.

Example of a simple tsconfig.json:

{
    "compilerOptions": {
        "target": "es6",
        "module": "commonjs",
        "strict": true
    },
    "include": ["src/**/*"],
    "exclude": ["node_modules"]
}

This file helps streamline project configuration and ensures consistent compilation behavior across different environments.

8. How does TypeScript handle null and undefined?

Answer:

TypeScript has strict null checks that help prevent errors related to null or undefined values. By default, both null and undefined are subtypes of all other types. However, when strict mode is enabled ("strictNullChecks": true), you must explicitly handle these values.

Example:

function greet(name?: string) {
    if (name) {
        console.log(`Hello, ${name}`);
    } else {
        console.log("Hello, guest");
    }
}

In this example, the parameter name is optional (can be undefined). The function checks if name has a value before using it.

To allow null values explicitly in your types, you can use union types:

let userName: string | null = null;

This approach enforces better handling of potentially missing values throughout your codebase.

9. What are decorators in TypeScript?

Answer:

Decorators are special annotations used to modify classes or their members (methods or properties) at design time. They provide a way to add metadata or modify behavior without changing the original code structure.

Types of decorators include:

  • Class Decorators: Applied to classes.
function LogClass(target: Function) {
    console.log(`Class created: ${target.name}`);
}

@LogClass
class User {}
  • Method Decorators: Applied to methods.
function LogMethod(target: any, propertyName: string, descriptor: PropertyDescriptor) {
    console.log(`Method called: ${propertyName}`);
}

class User {
    @LogMethod
    getName() {}
}

Decorators require enabling experimental features in your tsconfig.json:

{
    "experimentalDecorators": true
}

They are commonly used in frameworks like Angular for dependency injection and routing.

10. Can you explain what type inference is in TypeScript?

Answer:

Type inference is a feature in TypeScript where the compiler automatically deduces the type of a variable based on its initial value or context without requiring explicit type annotations from the developer. This helps reduce verbosity while maintaining strong typing benefits.

Example:

let num = 42; // inferred as number
let str = "Hello"; // inferred as string

function add(x = 0, y = 0) { // inferred as number
    return x + y;
}

In these examples, TypeScript infers the types of num, str, and parameters of the function based on their assigned values. This allows developers to write cleaner code without sacrificing type safety.

11. What is conditional typing in TypeScript?

Answer:

Conditional typing allows developers to define types based on conditions using the syntax:

T extends U ? X : Y

This means if type $$ T $$ extends $$ U $$, then use type $$ X $$; otherwise use type $$ Y $$. It’s useful for creating flexible types based on certain conditions.

Example:

type IsString<T> = T extends string ? "Yes" : "No";

type Test1 = IsString<string>; // "Yes"
type Test2 = IsString<number>; // "No"

In this example, IsString<T> checks if $$ T $$ is a string and returns corresponding results based on that condition.

12. How do you create an immutable object in TypeScript?

Answer:

To create an immutable object in TypeScript, you can use the readonly modifier for properties within an interface or class definition. This prevents properties from being modified after their initial assignment.

Example:

interface Point {
    readonly x: number;
    readonly y: number;
}

const pointA: Point = { x: 10, y: 20 };
// pointA.x = 15; // Error! Cannot assign to 'x' because it is a readonly property.

Using readonly helps enforce immutability throughout your codebase, making it easier to reason about state changes and reducing bugs related to unintended modifications.

13. Explain how modules work in TypeScript.

Answer:

Modules in TypeScript allow developers to organize code into separate files with their own scope. Each module can export its members (functions, classes, variables) so they can be imported into other modules using ES module syntax (import/export).

Example:

File1.ts:

export class Car {
    drive() {
        console.log("Driving...");
    }
}

File2.ts:

import { Car } from './File1';

const myCar = new Car();
myCar.drive(); // Outputs "Driving..."

Modules help maintain clean separation of concerns within applications and facilitate easier testing and maintenance by organizing related functionalities together.

14. How do you handle asynchronous programming in TypeScript?

Answer:

TypeScript supports asynchronous programming through Promises and async/await syntax just like modern JavaScript. This allows developers to write cleaner asynchronous code without deeply nested callbacks (callback hell).

Example using async/await:

async function fetchData(url: string): Promise<string> {
    const response = await fetch(url);
    const data = await response.text();
    return data;
}

fetchData('https://api.example.com/data')
    .then(data => console.log(data))
    .catch(error => console.error(error));

In this example, the function fetches data asynchronously using await so that execution pauses until the Promise resolves before proceeding further. This leads to more readable code compared to traditional Promise chaining methods.

15. What are tuples in TypeScript?

Answer:

Tuples are a special type of array where each element can have a different type defined at compile time. They allow you to express an array with fixed sizes and known data types for each position in that array.

Example:

let userInfo: [string, number] = ["Alice", 30];

console.log(userInfo[0]); // Outputs "Alice"
console.log(userInfo[1]); // Outputs 30

// userInfo[0] = 42; // Error! The first element must be a string.

In this example, userInfo is defined as a tuple containing a string followed by a number. This provides better structure compared to regular arrays where all elements would typically be of one type.

16. Explain how error handling works in TypeScript?

Answer:

Error handling in TypeScript works similarly to JavaScript since it compiles down to JavaScript code; however, with static typing benefits added by TypeScript’s features such as union types or custom error classes for better error management.

You can use try/catch statements for handling exceptions:

function riskyOperation(): number {
    throw new Error("Something went wrong!");
}

try {
    const result = riskyOperation();
} catch (error) {
    if (error instanceof Error) {
        console.error(error.message); // Outputs "Something went wrong!"
    }
}

Additionally, you can define custom error classes for more specific error handling scenarios:

class CustomError extends Error {
    constructor(message:string) {
        super(message);
        this.name = 'CustomError';
    }
}

throw new CustomError('This is a custom error!');

This approach allows developers to create more informative error messages tailored to specific scenarios within their applications while maintaining strong typing throughout their codebase.

17. What is template literal syntax in TypeScript?

Answer:

Template literals allow embedding expressions within strings using backticks (`). They support multi-line strings as well as interpolation via${expression}` syntax for including variables directly within strings without needing concatenation operators (+).

Example:

const name = 'John';
const greeting = `Hello ${name}, welcome!`;
console.log(greeting); // Outputs "Hello John, welcome!"

Template literals enhance readability when constructing strings dynamically compared to traditional concatenation methods while also allowing multi-line strings easily without escape characters for line breaks.

18. How do you convert between different data types in TypeScript?

Answer:

Type conversion between different data types can be achieved using built-in functions such as Number(), String(), or parsing functions like parseInt() and parseFloat() depending on your needs:

Example:

let numStr:string = "123";
let num:number = Number(numStr); // Converts string to number

let boolStr:string = "true";
let bool:boolean = boolStr === 'true'; // Converts string representation of boolean

let floatStr:string = "45.67";
let floatNum:number = parseFloat(floatStr); // Converts string to float

console.log(num);     // Outputs 123
console.log(bool);    // Outputs true
console.log(floatNum); // Outputs 45.67

These conversion functions help ensure proper handling when dealing with mixed-type data inputs throughout your application logic while maintaining strong typing benefits provided by TypeScripts’ features.

19. What are mixins in TypeScript?

Answer:

Mixins allow developers to create reusable components by combining multiple classes into one new class without traditional inheritance constraints through composition rather than inheritance alone—making it easier for sharing functionality across classes without creating deep inheritance hierarchies.

Example:

type Constructor<T> = new (...args:any[]) => T;

function Serializable<T extends Constructor<{}>>(Base:T) {

   return class extends Base {

       serialize() {

           return JSON.stringify(this);

       }

   };

}

class User {

   constructor(public name:string){}

}

const SerializableUser= Serializable(User);
const userInstance= new SerializableUser('Alice');
console.log(userInstance.serialize()); 

//Outputs '{"name":"Alice"}'

In this example we define mixin named Serializable which adds serialize method onto any base class passed into it allowing us reuse serialization logic across different classes easily.

20. How do you handle default parameters in functions?

Answer:

Default parameters allow specifying default values for function parameters when no argument or undefined is passed during invocation providing flexibility while reducing boilerplate checks inside function body.

Example:

function greet(name:string='Guest'){

   console.log(`Hello ${name}`);

}

greet();     // Outputs 'Hello Guest'

greet('Alice'); // Outputs 'Hello Alice'

In this case greet has default parameter set so if no argument provided during call it will fall back onto provided default value ensuring consistent behavior across invocations.

These questions cover essential aspects of TypeScript’s features and functionality that candidates should understand when preparing for interviews involving this powerful language used widely across modern web development projects!

Here is a list of additional TypeScript interview questions with detailed answers that build upon the basics:

21. What are Type Aliases in TypeScript, and how are they used?

Answer:

Type aliases in TypeScript are used to create a custom type by giving a name to a combination of types. They can be useful when dealing with complex data structures, making code more readable. Type aliases can represent primitive, union, tuple, or function types.

For example:

typescript type Point = { x: number; y: number };
let myPoint: Point = { x: 1, y: 2 };

They help make the code easier to understand and reuse, particularly when a type is used in multiple places.

22. What is the unknown type in TypeScript, and how does it differ from any?

Answer:

unknown is a safer alternative to any. It represents a type that could be anything, but you cannot perform operations on it without type-checking first. Unlike any, it restricts the code until the type is known.

any bypasses type-checking, whereas unknown requires validation, improving type safety.

23. How do Mapped Types work in TypeScript?

Answer:

Mapped types allow you to create new types by transforming the properties of an existing type. They’re commonly used with utility types like Partial or Readonly.

type Person = { name: string; age: number };
type ReadOnlyPerson = { readonly [K in keyof Person]: Person[K] };

Mapped types are useful for enforcing rules on properties, such as making them readonly or optional.

24. What is Type Assertion in TypeScript, and how is it different from Type Casting?

Answer:

Type assertions allow you to specify a variable’s type when you’re certain of its type. Unlike casting in other languages, type assertions don’t alter the runtime behavior.

let someValue: any = "Hello";
let strLength: number = (someValue as string).length;

This differs from casting, as assertions don’t change the value or perform conversion—they merely inform the TypeScript compiler about the type.

25. What is the never type, and when is it used in TypeScript?

Answer:

never is a type for values that never occur, often used in functions that never return, such as functions that throw errors or infinite loops.

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

It’s useful for exhaustive checks in switch cases, ensuring the code handles all cases.

26. Explain Union and Intersection Types in TypeScript.

Answer:

Union types allow a variable to hold one of several types, using the | operator.

let value: string | number;

Intersection types combine multiple types into one, using the & operator.

type A = { propA: string }; type B = { propB: number };
type C = A & B; // Must have both propA and propB

Union types provide flexibility, while intersection types enforce the presence of multiple types.

27. How does TypeScript handle Type Narrowing?

Answer:

Type narrowing is TypeScript’s way of refining types within a block based on conditions. TypeScript narrows the type by using type guards like typeof, instanceof, and custom type-checking functions.

This feature ensures that only valid operations for a narrowed type are allowed within a specific block.

28. What is typeof Type Guards in TypeScript?

Answer:

TypeScript uses typeof as a type guard to narrow the type of a variable in a conditional block. It’s particularly useful with union types.

Type guards enhance type safety by allowing operations specific to the narrowed type.

29. Explain the purpose of keyof operator in TypeScript.

Answer:

The keyof operator creates a union of the keys of a type. It’s useful in generic programming when you need to restrict a property to valid keys of a type.

keyof allows for safe access to object properties in generics by only permitting valid keys.

30. How do Conditional Types work in TypeScript?

Answer:

Conditional types in TypeScript allow defining types based on conditions, similar to ternary operators.
type IsString<T> = T extends string ? "Yes" : "No";

Conditional types are powerful in creating types based on logic, enabling dynamic type definitions.

31. What are Utility Types in TypeScript?

Answer:

TypeScript provides built-in utility types like Partial, Readonly, Pick, Omit, etc., to manipulate types.

Utility types reduce boilerplate and increase code readability by creating types based on existing structures.

32. Explain the concept of Index Signatures in TypeScript.

Answer:

Index signatures allow you to define a type for an object with unknown property names but a consistent type for values.

They’re useful for defining dictionaries or collections of related data.

33. What is Type Compatibility in TypeScript?

Answer:

TypeScript’s structural typing system focuses on the structure of types to determine compatibility. Types are compatible if they have the same properties.

This enables flexible and intuitive code reuse.

34. How does non-null assertion (!) operator work?

Answer:

The non-null assertion operator tells TypeScript that a variable isn’t null or undefined, bypassing strict null checks.

let value: string | undefined; console.log(value!.length);
// Asserts that `value` is non-null here

Useful in cases where you’re certain a variable is defined but TypeScript can’t infer it.

35. What is Discriminated Union in TypeScript?

Answer:

Discriminated unions are a type pattern using a common literal property in each member of a union. They simplify the process of narrowing types within a union.

They make code more readable and type-safe when working with complex data structures.

36. How does as const work in TypeScript?

Answer:

as const tells TypeScript to infer the most specific types for literal values.

For example:
const colors = ["red", "blue"] as const; // inferred as readonly ["red", "blue"]

It’s especially useful for ensuring data used in unions or discriminated unions remains constant.

37. What is the difference between type and interface?

Answer:

While interface is generally used to define object types and is extendable, type can define any kind of type, including primitives, unions, and intersections. Interfaces are preferable for extensibility, whereas types offer flexibility for complex structures.

38. Explain the concept of Optional Chaining in TypeScript.

Answer:

Optional chaining (?.) allows safely accessing deeply nested properties without checking each level.

const user = { address: { street: "Main St" } };
console.log(user.address?.street); // Safe access

It reduces code complexity when dealing with potentially undefined objects.

Learn More: Carrer Guidance

Operating System Interview Questions and Answers

Power BI Interview Questions with Detailed Answers

Java Microservices Interview Questions with Detailed Answers

OOP Interview Questions with Detailed Answers

React JS Interview Questions with Detailed Answers for Freshers

Cypress Interview Questions with Detailed Answers

PySpark interview questions and answers

Leave a Comment

Comments

No comments yet. Why don’t you start the discussion?

    Comments