30 Frontend Interview Questions - TypeScript

Yan Levin - Oct 2 - - Dev Community

TypeScript is one of the core skills for modern frontend developers. Mastering it includes not just basic syntax but deeper concepts like types, interfaces, generics, and how TypeScript interacts with JavaScript libraries. Below is a curated list of 30 interview questions targeting a frontend developer role with a focus on TypeScript.

Basic TypeScript Syntax & Features

1. What are the key differences between TypeScript and JavaScript?

  • TypeScript is a statically typed superset of JavaScript. It adds types, interfaces, and compile-time type checking, which JavaScript lacks. TypeScript transpiles to plain JavaScript, making it compatible with any JavaScript environment.

2. Why do we need TypeScript?

  • TypeScript helps catch errors at compile time, offers better tooling (autocomplete, refactoring), and ensures more maintainable and scalable code by enforcing strict typing rules.

3. What types exist in TypeScript?

  • TypeScript supports primitive types like string, number, boolean, undefined, null, symbol, and bigint. It also supports complex types like arrays, tuples, enums, any, unknown, void, never, objects, and union and intersection types.

4. What is the difference between type and interface?

  • type and interface both allow you to define custom types, but interface is better suited for defining shapes of objects, while type can handle more complex types such as unions and tuples.
   type CustomType = string | number;
   interface User {
     id: number;
     name: string;
   }
Enter fullscreen mode Exit fullscreen mode

5. What is your opinion on JSDoc as an alternative to TypeScript?

  • JSDoc is a documentation tool that can annotate types in JavaScript, but it doesn’t offer the same compile-time safety as TypeScript. JSDoc lacks many features TypeScript has, such as static analysis, which ensures code correctness before execution.

6. What are union types in TypeScript? Give an example.

  • A union type allows a value to be one of several types. It uses the | operator to combine types.
   function printId(id: number | string) {
     console.log(id);
   }
Enter fullscreen mode Exit fullscreen mode

7. How does TypeScript handle type assertions? Why should you use as?

  • Type assertions (using as or the angle bracket syntax) tell the TypeScript compiler that you know the type better than it does. It's used when you're sure about the type but TypeScript cannot infer it correctly.
   const value: any = "Hello";
   const strLength: number = (value as string).length;
Enter fullscreen mode Exit fullscreen mode

8. What is the difference between the unknown and any types?

  • unknown is safer than any. While any disables all type-checking, unknown forces you to perform type checks before manipulating the value.
   let data: unknown;
   data = "Hello";
   if (typeof data === "string") {
     console.log(data.toUpperCase());
   }
Enter fullscreen mode Exit fullscreen mode

9. What is the never type, and when would you use it?

  • The never type represents values that never occur. It's often used for functions that throw errors or infinite loops.
   function throwError(): never {
     throw new Error("This is an error");
   }
Enter fullscreen mode Exit fullscreen mode

10. What is type narrowing, and how does TypeScript implement it?

  • Type narrowing occurs when TypeScript reduces the type of a variable to a more specific type using type guards, such as typeof or instanceof.
   function padLeft(value: string | number) {
     if (typeof value === "string") {
       return value.padStart(10);
     }
     return value.toString();
   }
Enter fullscreen mode Exit fullscreen mode

Advanced Type Features

11. What are generics in TypeScript, and how do they contribute to reusability?

  • Generics allow you to create reusable components or functions that work with any type, providing flexibility and type safety.
   function identity<T>(arg: T): T {
     return arg;
   }
Enter fullscreen mode Exit fullscreen mode

Learn More

12. How do generics constraints work? Why are they useful?

  • You can constrain generics to ensure they meet certain conditions, such as having certain properties.
   function logLength<T extends { length: number }>(arg: T): void {
     console.log(arg.length);
   }
Enter fullscreen mode Exit fullscreen mode

13. Describe conditional types and when they can be utilized.

  • Conditional types allow you to create types that depend on a condition, enabling advanced type manipulation.
   type IsString<T> = T extends string ? true : false;
Enter fullscreen mode Exit fullscreen mode

14. What is the difference between the utility types Partial<T> and Pick<T, K>?

  • Partial<T> makes all properties in T optional. Pick<T, K> extracts specific properties from T.
   interface Person {
     name: string;
     age: number;
   }
   type PartialPerson = Partial<Person>;
   type NameOnly = Pick<Person, 'name'>;
Enter fullscreen mode Exit fullscreen mode

15. In TypeScript, what does keyof do?

  • keyof creates a union of the keys of an object type.
   interface Person {
     name: string;
     age: number;
   }
   type PersonKeys = keyof Person; // 'name' | 'age'
Enter fullscreen mode Exit fullscreen mode

16. How would you handle type-safe error handling with discriminated unions?

  • Discriminated unions allow you to handle different types in a safe way using a common discriminant property.
   type Success = { status: "success"; data: string };
   type Failure = { status: "failure"; error: string };
   type Response = Success | Failure;

   function handleResponse(response: Response) {
     if (response.status === "success") {
       console.log(response.data);
     } else {
       console.log(response.error);
     }
   }
Enter fullscreen mode Exit fullscreen mode

17. What are template literal types, and how useful are they?

  • Template literal types allow you to create new string types by combining unions of string literals, increasing flexibility in working with string types.
   type Greeting = `Hello, ${string}!`;
Enter fullscreen mode Exit fullscreen mode

TypeScript and OOP (Object-Oriented Programming)

18. How does TypeScript use classes? How do these differ from ES6 classes?

  • TypeScript classes extend ES6 classes with additional type annotations, access modifiers, and interfaces.
   class Person {
     private name: string;
     constructor(name: string) {
       this.name = name;
     }
     getName(): string {
       return this.name;
     }
   }
Enter fullscreen mode Exit fullscreen mode

19. What are access modifiers (public, private, protected) in TypeScript?

  • Access modifiers control the visibility of properties and methods. public means accessible everywhere, private within the class, and protected within the class and subclasses.

20. How do abstract classes work in TypeScript, and when should they be used?

  • Abstract classes define base classes with incomplete functionality, forcing subclasses to implement specific methods.
   abstract class Animal {
     abstract sound(): void;
     move() {
       console.log("Moving...");
     }
   }
   class Dog extends Animal {
     sound() {
       console.log("Woof!");
     }
   }
Enter fullscreen mode Exit fullscreen mode

21. What is the difference between an Interface and an Abstract Class?

  • An interface defines a contract (structure) without any implementation, whereas an abstract class can define both abstract methods and concrete methods.

22. How can you describe a class in TypeScript that we create inside a function and return outside?

  • You can create and return a class from within a function to provide encapsulation.
   function createUser() {
     return class User {
       constructor(public name: string) {}
     };
   }
   const UserClass = createUser();
   const user = new UserClass("John");
Enter fullscreen mode Exit fullscreen mode

TypeScript in React

23. How would you define types for props and state of a React component with TypeScript?

  • You can define props and state using interfaces or types.
   interface Props {
     title: string;
   }
   interface State {
     count: number;
   }
   class MyComponent extends React.Component<Props, State> {
     state: State = { count: 0 };
     render() {
       return <div>{this.props.title}</div>;
     }
   }
Enter fullscreen mode Exit fullscreen mode
  • To define types for props and state in a functional React component with TypeScript, you would use interface or type too. Since functional components don't have internal state like class components, you would type the props directly. However, for state managed by hooks like useState, you can also type those.
// Define the props type
interface Props {
  title: string;
}

const MyFunctionalComponent: React.FC<Props> = ({ title }) => {
  // Define the state with useState and give it a type
  const [count, setCount] = React.useState<number>(0);

  return (
    <div>
      <h1>{title}</h1>
      <p>Count: {count}</p>
      <button onClick={() => setCount(count + 1)}>Increment</button>
    </div>
  );
};
Enter fullscreen mode Exit fullscreen mode

24. What is the difference between using interface vs type for props in React components?

  • Both are commonly used, but interface is extendable, making it better for props composition, while type can handle more complex unions.

25. How would you type hooks with TypeScript?

  • Use types directly to hooks.
   const [count, setCount] = useState<number>(0);
Enter fullscreen mode Exit fullscreen mode

26. What's the difference between JSX.Element and React.ReactNode?

  • JSX.Element refers to a React element returned by a component, while React.ReactNode includes anything renderable by React, like strings, numbers, or fragments.

27. How do you type custom hooks in TypeScript?

  • Custom hooks are typed using generics, where necessary.
   function useCustomHook<T>(initialValue: T): [T, (value: T) => void] {
     const [state, setState] = useState(initialValue);
     return [state, setState];
   }
Enter fullscreen mode Exit fullscreen mode

TypeScript in Larger Projects

28. How would you manage complex types across multiple files in large-scale TypeScript projects?

  • Use TypeScript’s module system to split types across files and import them where needed. You can use index.ts for better type exports.
   // types.ts
   export interface User {
     id: number;
     name: string;
   }

   // index.ts
   export * from './types';
Enter fullscreen mode Exit fullscreen mode

29. How does functional programming in TypeScript differ from other approaches in other languages?

  • TypeScript enables functional programming by supporting higher-order functions, immutability, and strong type inference, similar to languages like Haskell or Scala, but retains the flexibility of JavaScript.

30. How would you ensure type safety when working with external services or REST APIs in TypeScript?

  • You can use TypeScript’s type system to define the expected API response shape and validate the types when consuming external data.
   interface ApiResponse {
     userId: number;
     id: number;
     title: string;
   }

   async function fetchPost(id: number): Promise<ApiResponse> {
     const response = await fetch(`https://jsonplaceholder.typicode.com/posts/${id}`);
     return response.json();
   }
Enter fullscreen mode Exit fullscreen mode

Preparing for these questions, studying the topics covered, and reviewing relevant resources can improve your chances of successfully passing the interview.

I look forward to your reactions and comments.💬
Good luck in your interview!🌟

. . . . . . . . . . . . . . . . . . .