Introduction
Welcome to Chapter 10: TypeScript MCQ Assessment. This chapter is designed to provide a quick yet comprehensive self-assessment of your TypeScript knowledge, ranging from foundational concepts to advanced architectural patterns. Multiple Choice Questions are an excellent tool for rapidly identifying strengths and weaknesses, reinforcing learned material, and preparing for the quick-fire knowledge checks often encountered in technical interviews.
The questions in this section are carefully crafted to cover the breadth of modern TypeScript usage as of January 2026, including features from TypeScript 5.x. We’ll delve into topics like structural typing, type inference, advanced generics, conditional and mapped types, utility types, effective type narrowing, tsconfig configurations, and real-world type challenges. This assessment is beneficial for candidates at all levels—entry-level professionals can solidify their understanding, mid-level developers can test their practical application, and senior/architects can validate their deep conceptual and design knowledge.
MCQ Section
Test your TypeScript expertise with these multiple-choice questions. Choose the best answer for each question.
Question 1: Structural Typing
Which of the following best describes TypeScript’s structural typing system?
A. Types are compatible if they share the same name. B. Types are compatible if they have the same members, regardless of their declared name. C. Types are compatible if they are explicitly declared to extend or implement each other. D. Types are compatible based on their runtime behavior, not their compile-time structure.
Correct Answer: B
Explanation:
- A. Types are compatible if they share the same name. Incorrect. TypeScript does not rely on nominal typing (name-based comparison).
- B. Types are compatible if they have the same members, regardless of their declared name. Correct. This is the definition of structural typing. If type A has all the members of type B (and their types are compatible), then A is assignable to B.
- C. Types are compatible if they are explicitly declared to extend or implement each other. Incorrect. While inheritance and interfaces are used, the underlying compatibility check is still structural.
- D. Types are compatible based on their runtime behavior, not their compile-time structure. Incorrect. TypeScript is a compile-time type checker; it doesn’t analyze runtime behavior for type compatibility.
Question 2: Conditional Types
Consider the following TypeScript code:
type IsString<T> = T extends string ? 'yes' : 'no';
type Result1 = IsString<'hello'>;
type Result2 = IsString<number>;
type Result3 = IsString<string | number>;
What will be the types of Result1, Result2, and Result3 respectively?
A. 'yes', 'no', 'yes' | 'no'
B. 'yes', 'no', 'yes'
C. 'yes', 'no', 'no'
D. 'yes', 'no', string
Correct Answer: A
Explanation:
- A.
'yes','no','yes' | 'no'Correct.Result1:'hello'extendsstring, so it’s'yes'.Result2:numberdoes not extendstring, so it’s'no'.Result3: When a conditional type is given a union type (likestring | number), it distributes over the union. This meansIsString<string | number>becomesIsString<string> | IsString<number>.IsString<string>resolves to'yes'.IsString<number>resolves to'no'.- Therefore,
Result3becomes'yes' | 'no'.
- B, C, D: Incorrect due to misunderstanding of conditional type distribution over unions.
Question 3: Mapped Types and as clause
Given the following type:
type User = {
id: number;
name: string;
email: string;
};
type ReadOnlyUser<T> = {
readonly [P in keyof T]: T[P];
};
type StrippedUser = {
[P in keyof User as P extends 'email' ? never : P]: User[P];
};
What will be the resulting type of StrippedUser?
A. { id: number; name: string; email: string; }
B. { id: number; name: string; }
C. { email: string; }
D. never
Correct Answer: B
Explanation:
- A, C, D: Incorrect.
- B.
{ id: number; name: string; }Correct. Theas P extends 'email' ? never : Ppart in the mapped type re-maps the keys. If a keyPis'email', it maps tonever, effectively removing it from the resulting type. Foridandname, they are not'email', so they are re-mapped to themselves, retaining their original types. This is a common pattern for picking or omitting properties.
Question 4: Type Narrowing
Consider the following function:
function processInput(input: string | number | string[]): string {
if (typeof input === 'string') {
return input.toUpperCase();
} else if (Array.isArray(input)) {
return input.join(', ');
} else {
// What is the type of 'input' here?
return String(input);
}
}
In the else block, what is the inferred type of input?
A. string | number | string[]
B. string | number
C. number | string[]
D. number
Correct Answer: D
Explanation:
- A, B, C: Incorrect.
- D.
numberCorrect.- The initial type of
inputisstring | number | string[]. - The first
if (typeof input === 'string')branch narrowsinputtostring. If this branch is taken, the function returns. - If the first branch is not taken, then in the
else ifblock,inputmust benumber | string[]. - The
else if (Array.isArray(input))branch narrowsinputtostring[]. If this branch is taken, the function returns. - If neither the
ifnor theelse ifbranches are taken, theninputcannot bestringand cannot bestring[]. Therefore, the only remaining possibility from its original union type isnumber. TypeScript’s control flow analysis correctly narrows the type.
- The initial type of
Question 5: tsconfig.json and strict mode
Which of the following options is NOT implicitly enabled when strict: true is set in tsconfig.json (as of TypeScript 5.x)?
A. noImplicitAny
B. strictNullChecks
C. noUncheckedIndexedAccess
D. strictFunctionTypes
Correct Answer: C
Explanation:
- A.
noImplicitAny: Enabled bystrict: true. Prevents implicitanytypes. - B.
strictNullChecks: Enabled bystrict: true. Enforces checking fornullandundefined. - C.
noUncheckedIndexedAccess: Correct. This option (introduced in TypeScript 4.1) is not part of thestrictflag. It must be enabled explicitly if desired. It makes indexed accesses (e.g.,arr[i]) potentiallyundefined. - D.
strictFunctionTypes: Enabled bystrict: true. Enforces stricter checking for function parameter types.
Question 6: Generics and Type Parameters
Consider the following generic function:
function identity<T>(arg: T): T {
return arg;
}
const num = identity<number>(123);
const str = identity('hello'); // Type inferred
What is the type of str?
A. any
B. unknown
C. string
D. T
Correct Answer: C
Explanation:
- A, B, D: Incorrect.
- C.
stringCorrect. Whenidentity('hello')is called without explicitly providing a type argument, TypeScript’s type inference mechanism correctly deduces thatTshould bestringbased on the argument'hello'. Therefore, the return type is alsostring.
Question 7: Declaration Merging
Which of the following TypeScript constructs cannot be merged using declaration merging?
A. Interfaces B. Namespaces (modules) C. Classes D. Enums
Correct Answer: C
Explanation:
- A. Interfaces: Correctly supports declaration merging. Multiple interface declarations with the same name are merged into a single interface.
- B. Namespaces (modules): Correctly supports declaration merging. Multiple namespace declarations with the same name are merged.
- C. Classes: Correct. Classes do not support declaration merging. You cannot declare two classes with the same name and expect their members to merge.
- D. Enums: Correctly supports declaration merging with namespaces (e.g., to add static members to an enum).
Question 8: Utility Types - Partial and Required
Given the type:
type UserProfile = {
id: number;
name: string;
email?: string;
};
What is the type of P1 and P2 respectively?
type P1 = Partial<UserProfile>;
type P2 = Required<UserProfile>;
A. P1: { id?: number; name?: string; email?: string; }, P2: { id: number; name: string; email: string; }
B. P1: { id: number; name: string; email?: string; }, P2: { id: number; name: string; email: string; }
C. P1: { id?: number; name?: string; email?: string; }, P2: { id?: number; name?: string; email?: string; }
D. P1: { id: number; name: string; email: string; }, P2: { id: number; name: string; email?: string; }
Correct Answer: A
Explanation:
- A.
P1: { id?: number; name?: string; email?: string; },P2: { id: number; name: string; email: string; }Correct.Partial<T>makes all properties ofToptional. So,idandnamebecome optional, andemailremains optional.Required<T>makes all properties ofTrequired. So,idandnameremain required, andemailbecomes required.
- B, C, D: Incorrect understanding of how
PartialandRequiredutility types modify optionality.
Question 9: unknown vs any
Which of the following statements about unknown and any is true?
A. Both unknown and any allow you to assign any value to them and access any property without type checking.
B. unknown requires type narrowing before accessing properties, while any does not.
C. any is a stricter type than unknown.
D. unknown can be assigned to any or void, but any cannot be assigned to unknown.
Correct Answer: B
Explanation:
- A. Both
unknownandanyallow you to assign any value to them and access any property without type checking. Incorrect. While both can receive any value,unknownprevents direct property access without narrowing. - B.
unknownrequires type narrowing before accessing properties, whileanydoes not. Correct. This is the primary distinction.unknownis type-safe; you must narrow its type (e.g., withtypeoforinstanceof) before performing operations on it.anybypasses all type checks. - C.
anyis a stricter type thanunknown. Incorrect.unknownis stricter thanany. - D.
unknowncan be assigned toanyorvoid, butanycannot be assigned tounknown. Incorrect.anycan be assigned tounknown. The key rule is thatunknowncan only be assigned toanyor itself, or a conditional type that checks its type.
Question 10: Discriminated Unions
Consider the following types:
interface SuccessResult {
status: 'success';
data: any;
}
interface ErrorResult {
status: 'error';
message: string;
}
type APIResult = SuccessResult | ErrorResult;
function handleResult(result: APIResult) {
if (result.status === 'success') {
// What is the type of 'result' here?
console.log(result.data);
} else {
// What is the type of 'result' here?
console.error(result.message);
}
}
In the if (result.status === 'success') block, what is the inferred type of result?
A. APIResult
B. SuccessResult
C. ErrorResult
D. SuccessResult | ErrorResult (still a union)
Correct Answer: B
Explanation:
- A, C, D: Incorrect.
- B.
SuccessResultCorrect. This is an example of a discriminated union. Thestatusproperty acts as a discriminant. Whenresult.status === 'success'is checked, TypeScript’s control flow analysis can precisely narrow the type ofresultfromAPIResulttoSuccessResult, allowing safe access to itsdataproperty. Conversely, in theelseblock,resultwould be narrowed toErrorResult.
Practical Tips
- Understand the “Why”: Don’t just memorize answers. For each MCQ, understand why the correct answer is correct and why the incorrect ones are wrong. This builds deeper conceptual understanding.
- Focus on Core Concepts: Many advanced TypeScript features build upon fundamental ideas like structural typing, type inference, and union types. Ensure your foundation is solid.
- Practice Type Transformations: Pay special attention to how utility types, conditional types, and mapped types transform existing types. These are frequently tested in advanced scenarios.
- Know
tsconfig.json: Understand the impact of key compiler options, especially those related to strictness (strict,noImplicitAny,strictNullChecks, etc.). This reflects architectural awareness. - Distinguish
any,unknown,never,void: These special types have specific use cases and implications for type safety. Be clear on their differences. - Read Official Docs (TypeScript 5.x): The TypeScript documentation is the most authoritative source. Keep up-to-date with new features and changes in TypeScript 5.x and beyond.
- Code and Experiment: The best way to internalize these concepts is to write small code snippets that demonstrate the behavior of types, especially for tricky areas like conditional type distribution or complex mapped types.
Summary
This MCQ assessment provided a snapshot of your TypeScript knowledge across a range of topics, from fundamental type system behaviors to advanced type transformations and compiler configurations. A strong performance here indicates a solid grasp of TypeScript’s capabilities and best practices as of 2026. If you found certain areas challenging, use the explanations and practical tips to guide your further study. Continuous learning and practical application are key to mastering TypeScript and excelling in interviews.
References
- TypeScript Handbook (Official Documentation): The definitive guide to TypeScript, covering all features and best practices.
- TypeScript
tsconfig.jsonReference: Detailed explanations of all compiler options. - Ultimate Guide to Acing Your Technical Interview (InterviewBit): General technical interview preparation resources.
- TypeScript Advanced Types: Mapped Types and Conditional Types (Medium): A good resource for understanding these complex type features.
- GeeksforGeeks - TypeScript Conditional and Mapped Types: Another resource for specific advanced type topics.
This interview preparation guide is AI-assisted and reviewed. It references official documentation and recognized interview preparation resources.