TypeScript MCQs - Advanced Types: Conditional, Mapped and Template Literals (Set 4)

TypeScript MCQs - Advanced Types: Conditional, Mapped and Template Literals (Set 4) - CodingHumans

Set 4 goes deeper into programming with types: conditional types with infer, renaming keys in mapped types, template literal types and the rules of variance. Each answer walks through how the compiler gets to the result, so you can work out similar types in interviews and in library code.

How to practise: read each question and tap the option you think is correct. You will see right away whether you got it, along with a short explanation, and your score is tracked at the bottom of the screen. This set has 15 questions.

TypeScript MCQ series: Set 1 | Set 2 | Set 3 | Interview Preparation Hub

Topics covered in this set

  • infer in arrays, functions and template strings
  • Distributive vs non-distributive conditional types
  • Key remapping with as and modifier removal
  • Template literal and intrinsic string types
  • Variance: covariance, contravariance and in/out
  • satisfies combined with as const

TypeScript MCQs with answers and explanations

Q1. What is A?

type ElementType<T> = T extends (infer U)[] ? U : T;
type A = ElementType<string[]>;

a) string

b) unknown

c) string[]

d) never

Q2. What is FA?

type FirstArg<F> =
  F extends (a: infer A, ...rest: any[]) => any ? A : never;
type FA = FirstArg<(x: number, y: string) => void>;

a) string

b) number

c) never

d) [number, string]

Q3. What is T2?

type ToArr<T> = T extends any ? T[] : never;
type T2 = ToArr<string | number>;

a) (string | number)[]

b) any[]

c) string[] | number[]

d) never

Q4. How do you stop a conditional type from distributing over a union?

a) Use infer

b) Add readonly to T

c) Wrap both sides in a tuple, as in [T] extends [any]

d) Use T extends unknown

Q5. Why is IsNever usually written with tuples, as below?

type IsNever<T> = [T] extends [never] ? true : false;

a) never is an empty union, so a naked T extends never would distribute over nothing and return never instead of true

b) never cannot appear in conditional types otherwise

c) It is only a style choice

d) Tuples are faster to compile

Q6. What keys does G have?

type Getters<T> = {
  [K in keyof T as `get${Capitalize<string & K>}`]: () => T[K];
};
type G = Getters<{ name: string; age: number }>;

a) get and Name

b) getname and getage

c) getName and getAge

d) name and age

Q7. In a mapped type with key remapping, how do you drop a key such as "id"?

a) Map it to never in the as clause, for example as Exclude<K, "id">

b) Use the ?: modifier

c) Use delete in the type

d) Map it to undefined

Q8. What does this mapped type do?

type Mut<T> = { -readonly [K in keyof T]-?: T[K] };

a) Removes readonly and makes every property required

b) Converts properties to methods

c) Removes all properties

d) Makes every property readonly and optional

Q9. How many members does Size have?

type Size = `${"sm" | "md" | "lg"}-${"red" | "blue"}`;

a) 2

b) 5

c) 6

d) 1

Q10. What is P?

type Param<S> = S extends `${string}:${infer P}` ? P : never;
type P = Param<"/users/:id">;

a) "id"

b) "/users/"

c) string

d) never

Q11. With strictFunctionTypes enabled, which assignment is allowed?

let wide: (x: string | number) => void = () => {};
let narrow: (x: string) => void = () => {};

a) Both

b) wide = narrow

c) Neither

d) narrow = wide

Q12. What do the in and out modifiers on a type parameter, as in interface Box<out T>, do?

a) They mark T as optional

b) They declare the variance of T (out = covariant, in = contravariant) so the compiler can check and use it

c) They only work on classes

d) They change runtime behaviour

Q13. What is Item?

const roles = ["admin", "editor", "viewer"] as const;
type Item = (typeof roles)[number];

a) "admin" | "editor" | "viewer"

b) readonly string[]

c) string

d) string[]

Q14. Why combine as const with satisfies, as in const routes = { home: "/" } as const satisfies Record<string, string>?

a) It has no effect

b) satisfies removes the readonly modifiers

c) The object keeps its literal, readonly types while still being checked against the wider shape

d) It converts the object to an enum

Q15. What is the result of Awaited<Promise<Promise<number>>>?

a) Promise<Promise<number>>

b) unknown

c) Promise<number>

d) number

Quick revision notes

  • infer pulls out part of a matched type: array elements, parameters, return types or pieces of a string.
  • Bare type parameters distribute over unions. Wrap them in [T] to stop that.
  • Key remapping with as can rename keys or drop them by mapping to never.
  • Template literal types expand unions into every combination.
  • Parameters are contravariant. as const with satisfies gives you checked literal types.

Frequently asked questions

Do I need advanced types in day-to-day application code?

Mostly no. They matter when you write shared utilities, typed API clients or libraries. But being able to read them helps you understand library types and error messages.

Why does my conditional type return a union when I expected one result?

The checked type was a bare type parameter that got a union, so it distributed. Wrap both sides in tuples to check the union as one piece.

Do template literal types have a runtime cost?

No. Like every TypeScript type, they are removed when you compile and only affect type checking.

Comments

Answered 0/0Correct 0