Most asked TypeScript interview questions 🚀
Tags: typescript, programming, interview, tutorial
Published: 2023-12-05 11:50:46

## Introduction 🌐

Welcome to the Most asked TypeScript Interview Questions guide, your ultimate prep tool for mastering TypeScript interviews! 🚀 From the fundamentals to advanced concepts, we've got you covered. Let's get started!

---

## Beginner Level 🧑‍💻

### What is TypeScript and why should we use it?

- **Enhanced Language:** TypeScript extends JavaScript with features like **type checking**, access modifiers, and interfaces.
- **Error Prevention:** TypeScript helps avoid common JavaScript errors, ensuring more reliable production-ready code.

![JS errors](https://i.imgur.com/MNCVx55.png)

Learn more about common errors in JavaScript [here](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Errors).

- **Developer Experience:** Offers improved developer experiences with enhanced IntelliSense and code suggestions directly within the editor.

### What are the basic types in TypeScript?

In TypeScript, we have basic types that align with the fundamental data types in JavaScript. These include `number`, `string`, `boolean`, `null`, `undefined`, and `symbol`. For example:

```typescript
let name: string = "Ramu";
let age: number = 24;
let isValid: boolean = false;
let user: null = null;
let value: undefined = undefined;
let uniqueKey: symbol = Symbol("key");
```

### What are access modifiers in TypeScript?

In TypeScript, access modifiers manage how parts of your code are shared. There are three key access modifiers: `private`, `public`, and `protected`.

- **Private:** Variables or methods marked as `private` are exclusive to their class. They cannot be accessed from outside that class.

  ```typescript
  class Example {
    private secret: string = "hidden information";
  }
  ```

- **Public:** Using `public` makes variables or methods accessible from anywhere in the program.

  ```typescript
  class Example {
    public info: string = "public information";
  }
  ```

- **Protected:** When declared `protected`, variables or methods are accessible within the class and its subclasses.

```typescript
class BaseClass {
  protected internalData: string = "accessible within subclasses";
}

class SubClass extends BaseClass {
  constructor() {
    super();
    console.log(this.internalData);
  }
}
```

### Explain how TypeScript infers types?

TypeScript uses **type inference** to automatically determine the types of variables based on their assigned values while declaration. For example:

```typescript
let age = 25; // TypeScript infers `age` as type `number`.
let name = "Ramu"; // TypeScript infers `name` as type `string`.
let isValid = true; // TypeScript infers `isValid` as type `boolean`.
```

### What is an interface in TypeScript, and how is it different from a class?

In TypeScript, an interface serves as a blueprint for defining how an object should look. It outlines the properties an object should have and their respective types but doesn't include any actual code.

Unlike a class, an interface is solely used to describe the structure of an object. For example:

```typescript
interface Person {
  name: string;
  age: number;
}

const ramu: Person = {
  name: "Ramu",
  age: 24,
};
```

In this example, the `Person` interface helps us define what properties a `ramu` object should have – in this case, a `name` of type `string` and an `age` of type `number`.

### What is the difference between `never`, `unknown`, and `any` in TypeScript?

| Type      | Description                                                                                                                                                         |
| --------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `never`   | TypeScript completely skips type checking for variables assigned with `never`. It signifies absolute absence of value.                                              |
| `unknown` | Assigning a variable with `unknown` tells TypeScript it's uncertain about the variable's type. Unlike `any`, it enforces type checks for safety.                    |
| `any`     | TypeScript skip all type checks for variables assigned with `any`, providing maximum flexibility but sacrificing static typing benefits. It's a free pass for types. |

For example:

```typescript
// This function is intentionally created to generate an error and never return a value.
function throwError(message: string): never {
  throw new Error(message);
}
```

```typescript
let person: unknown;

// Since TypeScript identifies 'person' as an unknown type, we need to perform multiple type-checks.
if (
  !!person &&
  typeof person === "object" &&
  "name" in person &&
  "age" in person
) {
  // After confirming its type, we can safely assign values to its properties.
  person.name = "Ramu";
  person.age = 24;
}
```

```typescript
// A variable declared with 'any' type allows assigning values of any data type to it.
let value: any;

// Examples of assigning various types of values to the 'value' variable.
value = 23;
value = "Hi folks...";
value = true;
```

### What is the difference between `type` and `interface` in TypeScript?

**Defining Properties**

- **`type`:** Define types for values or combinations, including primitives.

  ```typescript
  type Age = number;
  type Name = string;

  type PersonType = {
    name: Name;
    age: Age;
  };
  ```

- **`interface`:** Ideal for shaping object structures.

  ```typescript
  interface PersonInterface {
    name: string;
    age: number;
  }
  ```

**Extending**

- **`type`:** Extend using `&` for easy combination.

  ```typescript
  type PersonType = { name: string; age: number };
  type PlayerType = PersonType & { isCricketer: boolean };
  ```

- **`interface`:** Extend using `extends` for inheritance.

  ```typescript
  interface PersonInterface {
    name: string;
    age: number;
  }
  interface PlayerInterface extends PersonInterface {
    isCricketer: string;
  }
  ```

**Declaration Merging**

- **`type`:** Does not support merging; duplicate definitions raise an error.

  ```typescript
  type Person = { name: string };
  // Error: Duplicate identifier 'Person'.
  type Person = { age: number };
  ```

- **`interface`:** Supports merging, enabling extension or addition.

  ```typescript
  interface Person {
    name: string;
  }
  // Extends the existing Person interface.
  interface Person {
    age: number;
  }
  ```

**Immutability**

- **`type`:** Allows flexibility, making properties readonly or optional.

  ```typescript
  type ReadonlyPerson = { readonly name: string; readonly age: number };
  type OptionalPerson = { name?: string; age?: number };
  ```

- **`interface`:** Direct support for readonly or optional properties is limited.

```typescript
  // Error: 'readonly' modifier cannot be used with an index signature.
  interface ReadonlyPerson {
    readonly [key: string]: string | number;
  }
  // Error: An index signature parameter type cannot be optional.
interface OptionalPerson { [key: string]?: string | number; }
```

**Choosing Between `type` and `interface`**

- **`type`:** Use for unions, intersections, or with primitive types.

- **`interface`:** Ideal for defining object shapes, extending, or leveraging declaration merging.

---

## Intermediate Level 🚧

### What are generics in TypeScript, and when would you use them?

Generics in TypeScript enable you to create versatile and reusable code. They let you write functions and classes that can work with different types. For example:

```typescript
function print<T>(arg: T): T {
  return arg;
}

const resultNum = print<number>(42);
const resultStr = print<string>("Hi folks...");
```

In this example, the `print` function uses a generic type `T`, allowing it to work with both numbers and strings. The function returns the input value as is, demonstrating flexibility with various data types.

### What are Union and Intersection Types in TypeScript?

In TypeScript, union types, marked by `|`, allow a variable to have values from different types. It means the variable can store values that match any of the specified types.

For example:

```typescript
type Cat = { name: string; meow: () => void };
type Dog = { name: string; bark: () => void };

const pet: Cat | Dog = /* Either a Cat or a Dog */;
```

On the other side, intersection types, shown by `&`, bring together multiple types to form a new type with all the properties of each individual type.

For example:

```typescript
type Name = string;
type Age = number;

type Person = Name & Age; // `Person` must have properties from both `Name` and `Age`.

const person: Person = { name: "Ramu", age: 24 };
```

### When would you use type assertion in TypeScript?

Type assertion is used when you know more about a value's type than TypeScript does. For example:

```typescript
let arr: any = [1, 2, 3];
let len: number = (arr as number[]).length;
```

---

## Advanced Level 🔥

### What are mapped types, and how do they work in TypeScript?

Mapped types in TypeScript allow you to create new types by changing the properties of existing ones. For instance:

```typescript
type Person = {
  name: string;
  age: number;
};

// Create a type where all parameters are optional
type OptionalType<T> = { [K in keyof T]?: T[K] };
const optionalPerson: OptionalType<Person> = {
  name: "Ramu",
};

// Create a type where all parameters are required
type RequiredType<T> = { [K in keyof T]: T[K] };
const requiredPerson: RequiredType<Person> = {
  name: "Ramu",
  age: 24,
};
```

However, TypeScript provides built-in `Partial` and `Required` types, which you can use directly instead of defining custom `OptionalType` and `RequiredType` types. For example:

```typescript
type Person = {
  name: string;
  age: number;
};

// Use Partial<T> for optional properties
const optionalPerson: Partial<Person> = {
  name: "Ramu",
};

// Use Required<T> directly for required properties
const requiredPerson: Required<Person> = {
  name: "Ramu",
  age: 24,
};
```

### What are Conditional Types in TypeScript?

Conditional types in TypeScript help us describe different type mappings based on certain conditions. Let's break it down with an example:

```typescript
type IfString<T> = T extends string ? "It's a string" : "It's not a string";
let result: IfString<number>; // "It's not a string"
```

In this example, `IfString` is a conditional type that checks if the provided type (`T`) is a string. If it is, it returns "It's a string"; otherwise, it returns "It's not a string." The `result` variable, declared as `IfString<number>`, illustrates that the type is not a string, confirming our condition.

### What are TypeScript decorators, and how do they work?

Decorators are a way to modify or annotate classes and properties in TypeScript. For example:

```typescript
function log(target: any, key: string) {
  console.log(`Property ${key} has been accessed`);
}

class MyClass {
  @log
  myProperty: string = "example";
}
```

### Explain the concept of advanced type guards.

Advanced type guards involve using user-defined functions to narrow down the type of a variable within a certain code block. For example:

```typescript
interface Cat {
  name: string;
  meow(): void;
}

interface Dog {
  name: string;
  bark(): void;
}

function isCat(animal: Cat | Dog): animal is Cat {
  return "meow" in animal;
}

const pet: Cat | Dog = /* initialize */;
if (isCat(pet)) {
  pet.meow(); // TypeScript knows `pet` is a Cat here.
} else {
  pet.bark(); // TypeScript knows `pet` is a Dog here.
```

### What is the `declare` keyword in TypeScript?

The `declare` keyword in TypeScript is used to inform the compiler that a variable, method, or library is defined externally and its type information is not available within the current TypeScript code.

This is often used when working with plain JavaScript libraries that lack TypeScript typings.

#### Example:

```typescript
// externalModule.js
// This is a plain JavaScript module without TypeScript typings
const externalModule = {
  print: function (name) {
    console.log(`Hello, ${name}!`);
  },
};

// yourModule.ts
// TypeScript file where you want to use externalModule

declare var externalModule: any;

externalModule.print("Ramu"); // No type checking for externalModule
```

---

Thank you for reading this far; your support means a lot! If you have any questions, please don't hesitate to ask in the comments. Don't forget to like and share the article – your appreciation is highly valued. Your feedback and suggestions are also more than welcome. 🙏👍😊