Unit 5 - Practice Quiz
1 What is the primary benefit of using TypeScript over plain JavaScript?
2 Which company developed and maintains TypeScript?
3
What does the TypeScript compiler (tsc) convert TypeScript code into?
4
How do you explicitly assign a string type to a variable named username in TypeScript?
let username is string;
let username: string;
string username;
let username = string;
5
Which built-in type in TypeScript can hold true or false values?
number
boolean
string
any
6 Which keyword is used to create a new name for a type, such as a union of other types?
alias
type
interface
typedef
7
What is the primary purpose of an interface in TypeScript?
8 Which character is used to create a union type, allowing a variable to be one of several types?
? (question mark)
& (ampersand)
% (percent)
| (pipe)
9 What is type inference in TypeScript?
10 What is the standard file extension for a TypeScript file?
.tsc
.ts
.tsx
.js
11
What does the any type represent in TypeScript?
12 What is the main advantage of using generics in TypeScript?
13
Given let score = 100;, what type does TypeScript infer for the score variable?
boolean
number
string
any
14
What does the type string & number resolve to?
string | number
never
number
string
15
In the context of generics, what does T in <T> typically stand for?
16 Is TypeScript a statically typed or a dynamically typed language?
17 What is the most common name for the TypeScript configuration file?
typescript.json
tsconfig.json
config.ts
package.json
18
What is the purpose of using a typeof check inside an if statement in TypeScript?
19
Can a class implement an interface in TypeScript?
implements keyword.
extends keyword.
20 How would you define an array of numbers in TypeScript?
Array<number> or number[]
[number]
numbers()
array: number
21 What is the primary reason for using TypeScript in a large, team-based JavaScript project?
22
Consider the following code. What will be the output of the TypeScript compiler?
typescript
let data: unknown;
data = "Hello, world!";
// What happens at this line?
console.log(data.toUpperCase());
data is unknown.
undefined.
23
Which of the following statements accurately describes a key difference between interface and type aliases in TypeScript?
interface can be implemented by a class.
interface declarations can be merged (declaration merging), while type aliases cannot.
type aliases can be used to define union types.
type aliases are hoisted, but interface declarations are not.
24
Given the following types, which object is a valid instance of AdminUser?
typescript
type User = {
id: number;
name: string;
};
type Admin = {
id: number;
permissions: string[];
};
type AdminUser = User & Admin;
{ id: 1, name: 'Alice', permissions: ['read'] }
{ name: 'Bob', permissions: ['delete'] }
{ id: 1, name: 'Alice' }
{ id: 1, permissions: ['write'] }
25
What is the purpose of the extends keyword in the following generic function signature?
typescript
function getProperty<T, K extends keyof T>(obj: T, key: K) {
return obj[key];
}
K must be a type that is assignable to one of the keys of T.
T is a subclass of K.
T.
T and K.
26
Analyze the code below. What is the inferred type of the statusMessage variable?
typescript
function getStatus(code: number) {
if (code < 400) {
return { success: true, code };
} else {
return { success: false, error: Error code: ${code} };
}
}
const statusMessage = getStatus(200);
any
{ success: boolean; code: number; error: string; }
{ success: true; code: number; } | { success: false; error: string; }
{ success: boolean; code?: number; error?: string; }
27
What is the primary effect of setting "noImplicitAny": true in the tsconfig.json file?
any types to unknown during compilation.
unknown instead of any.
any type completely throughout the project.
any type.
28
Which type annotation should be used for the employee parameter in the following function to ensure it receives an array where the first element is a string (name) and the second is a number (id)?
typescript
function processEmployee(/ employee: ??? /) {
const name = employee[0]; // should be string
const id = employee[1]; // should be number
}
{string, number}
Array<string | number>
(string | number)[]
[string, number]
29
Given the following Logger interface and FileLogger class, why does the TypeScript compiler show an error?
typescript
interface Logger {
log(message: string): void;
}
class FileLogger implements Logger {
log(message: string, level: string): void {
console.log([{message});
}
}
log method in FileLogger has a different method signature than the one defined in the Logger interface.
implements Logger clause.
log method in the interface must be marked as public.
30
Why does the following function produce a TypeScript error?
typescript
function formatInput(input: string | number) {
// Error on the next line
return input.trim();
}
trim method does not exist on the number type, and TypeScript cannot guarantee input is a string.
input parameter must be an intersection type (string & number) to have methods from both types.
31
Consider this generic interface. Which of the following variable declarations is valid?
typescript
interface ApiResponse<T> {
data: T;
status: number;
}
interface User {
id: number;
username: string;
}
const response: ApiResponse<User> = { data: { id: 1, username: 'test' }, status: 200 };
const response: ApiResponse<User> = { data: { id: 1 }, status: 200 };
const response: ApiResponse = { data: { id: 1, username: 'test' }, status: 200 };
const response: ApiResponse<User> = { data: 'some user', status: 404 };
32
In the code below, what is the type of pet inside the if block?
typescript
interface Cat {
meow(): void;
}
interface Dog {
bark(): void;
}
function makeSound(pet: Cat | Dog) {
if ('bark' in pet) {
// What is the type of pet here?
pet.bark();
}
}
any
Cat | Dog
Dog
Cat
33
What is the primary use case for creating a type alias for a union of string literals, as shown below?
typescript
type OrderStatus = 'pending' | 'shipped' | 'delivered' | 'cancelled';
let currentStatus: OrderStatus = 'pending';
currentStatus to be any string at runtime.
OrderStatus.
currentStatus, providing type safety and autocompletion.
34
Which of the following function calls would cause a TypeScript compilation error?
typescript
function merge<T extends object, U extends object>(objA: T, objB: U) {
return { ...objA, ...objB };
}
merge({ id: 1 }, { data: ['a', 'b'] })
merge({ value: null }, { enabled: true })
merge({ name: 'Max' }, { age: 30 })
merge({ name: 'Max' }, 30)
35
Consider the following discriminated union. Why is the access to c inside the 'circle' case valid?
typescript
interface Square { kind: 'square'; size: number; }
interface Circle { kind: 'circle'; radius: number; }
type Shape = Square | Circle;
function getArea(s: Shape) {
switch (s.kind) {
case 'square': return s.size s.size;
case 'circle': return Math.PI s.radius ** 2;
}
}
s to type any inside the switch statement.
switch statement on the kind property narrows the type of s to Circle within that case block.
radius is an optional property on the Shape type.
36
What is the resulting type of Combined?
typescript
interface A { a: number; b: string; }
interface B { b: number; c: boolean; }
type Combined = A & B;
{ a: number; b: never; c: boolean; }
{ a: number; b: string | number; c: boolean; }
{ a: number; b: any; c: boolean; }
{ a: number; b: number; c: boolean; }
37 How does TypeScript relate to the ECMAScript (ES) standard?
38
A function is intended to accept a callback that takes no arguments and doesn't return a value. What is the correct type annotation for the callback parameter?
typescript
function executeCallback(callback: / ??? /) {
callback();
}
Function
() => void
(any) => any
void
39
You want to create a function that takes an array of any type and returns a new array with duplicate values removed. Which function signature is the most appropriate and type-safe?
typescript
// function unique(arr: ???): ??? { ... }
unique(arr: unknown[]): unknown[]
unique<T>(arr: Array<T>): Array<any>
unique<T>(arr: T[]): T[]
unique(arr: any[]): any[]
40
What happens if a class implements an interface with an optional property, but the class does not declare that property?
typescript
interface Options {
timeout?: number;
retries: number;
}
class Config implements Options {
retries: number = 3;
}
timeout property of type any to the Config class.
timeout is missing.
Config is created.
41
Consider the following TypeScript code. What is the inferred type of result?
typescript
function keyRemover<T, K extends keyof T>(obj: T, key: K): Omit<T, K> {
const { [key]: _, ...rest } = obj;
return rest;
}
const user = {
id: 1,
name: 'Alice',
email: 'alice@example.com'
};
const keyToOmit = 'id' as const;
const result = keyRemover(user, keyToOmit);
result is inferred as Omit<{ id: number; name: string; email: string; }, "id">.
result is inferred as Partial<{ name: string; email: string; }>.
result is { name: string; email: string; }.
[key] is not type-safe for creating an Omit type.
42
Analyze the following TypeScript function. Which statement accurately describes the type of data at the marked point?
typescript
type Success = { status: 'success'; data: string };
type Loading = { status: 'loading' };
type Error = { status: 'error'; error: Error };
type State = Success | Loading | Error;
function processState(state: State) {
if (state.status === 'success' || state.status === 'loading') {
return;
}
// What is the type of state here?
const { error } = state;
console.log(error.message);
}
state is State, and the code compiles without error.
state is narrowed to Error.
state is of type Error, but Error is also the name of a built-in JavaScript class, causing a conflict.
state is never, because all possible cases are handled in the if block.
43
What is the resulting type of Combined and why?
typescript
type FuncA = (a: string, b: number) => void;
type FuncB = (a: string) => void;
type Combined = FuncA & FuncB;
const fn: Combined = (a: string, b?: number) => {};
Combined is an overloaded function type that can be called with either (a: string, b: number) or (a: string). The implementation must be compatible with the most specific signature, (a: string, b: number) => void.
Combined is a single function signature (a: string, b: number) => void, because it's the more specific of the two, and fn is a valid implementation.
Combined is a single function signature (a: string) => void, because it's the more lenient of the two.
44
Given the following interface with an index signature, why does the TypeScript compiler raise an error?
typescript
interface StringMap {
[key: string]: string;
length: number;
}
length property is missing an explicit public accessor.
length is a reserved keyword and cannot be used in interfaces.
length property, number, is not assignable to the value type of the string index signature, string.
45
What is the behavior of the following conditional type IsString<T> when applied to a union type?
typescript
type IsString<T> = T extends string ? true : false;
type Result = IsString<string | number>;
Result is false, because the entire union string | number does not extend string.
Result is boolean, because the condition is checked for each member of the union, resulting in true | false.
Result is true, because at least one member of the union extends string.
46
In the context of function types, what do covariance and contravariance refer to, and which example correctly demonstrates one of them?
typescript
class Animal {}
class Dog extends Animal {}
// Which assignment is valid and why?
let processAnimal: (a: Animal) => void;
let processDog: (d: Dog) => void;
processDog = processAnimal; is valid. This is covariance, where a function can accept a more general type in place of a specific one.
processAnimal = processDog; is valid. This is covariance, as the parameter type is more specific.
processDog = processAnimal; is valid. This is contravariance, where a function expecting a more specific type can be assigned a function that handles a more general type.
47
You have a project with "noEmitOnError": true in your tsconfig.json. You run tsc and it reports a single type error in file.ts. What is the state of your output directory (e.g., dist) after the compilation attempt?
dist/file.js is generated, but it contains comments indicating where the type error occurred.
dist/file.js will be missing.
dist/file.js, are generated, but the compiler exits with a non-zero status code.
48
What is the evaluated type of Result? Analyze the interaction between the mapped type and the intersection.
typescript
type Properties = 'name' | 'age';
type Mapped = { [K in Properties]: { [P in K]: P extends 'name' ? string : number } };
type Result = Mapped['name'] & Mapped['age'];
{ name: string; } | { age: number; }
{ name: string; age: number; }
never
49
Examine this custom type guard. Why is it considered an anti-pattern or potentially unsafe, despite compiling successfully?
typescript
interface Car { drive: () => void; }
interface Bike { ride: () => void; }
function isCar(vehicle: Car | Bike): vehicle is Car {
return (vehicle as Car).drive !== undefined;
}
const myBike: Bike = { ride: () => {} };
if (isCar(myBike)) {
// What is problematic here?
myBike.drive(); // Compiles, but will crash at runtime
}
'drive' in vehicle is a more robust way to check for the property's existence and should be used instead.
drive property with a value of null or undefined, which would satisfy the check but not be a function.
instanceof Car instead of property checking.
vehicle is Car is incorrect; it should be boolean.
50
What is the inferred return type of the getDeepValue function in the following example?
typescript
function getDeepValue<T, K1 extends keyof T, K2 extends keyof T[K1]>(obj: T, key1: K1, key2: K2): T[K1][K2] {
return obj[key1][key2];
}
const data = {
user: {
id: 1,
name: 'John Doe',
address: {
street: '123 Main St',
city: 'Anytown'
}
},
posts: []
};
const cityName = getDeepValue(data, 'user', 'address');
K2.
cityName is { street: string; city: string; }.
K2 cannot be constrained by keyof T[K1].
cityName is unknown because the depth is too complex for TypeScript.
51
Given the following function that uses variadic tuple types and a const assertion, what is the inferred type of tupleTail?
typescript
function tail<T extends any[]>(arr: readonly [any, ...T]) : T {
const [_head, ...rest] = arr;
return rest;
}
const myTuple = [10, 'hello', true] as const;
const tupleTail = tail(myTuple);
readonly ['hello', true]
(string | boolean)[]
[string, boolean]
['hello', true]
52
What will be the type of config.apiKey and why does the following code behave as it does?
typescript
interface BaseConfig {
readonly apiKey: string;
}
interface Config extends BaseConfig {
apiKey: string; // Attempt to override readonly
}
function setKey(config: Config) {
config.apiKey = 'new-key'; // Is this allowed?
}
const myConfig: Config = { apiKey: 'old-key' };
setKey(myConfig);
config.apiKey is mutable (string) because the extending interface Config overrides the readonly modifier.
setKey function call because myConfig's apiKey is implicitly readonly.
config.apiKey.
Config cannot override readonly apiKey with a mutable one.
53
Consider the assert function below. After the assertion, person.name can be used as a string. What TypeScript concept makes this possible?
typescript
interface Person {
name?: string;
age: number;
}
function assert(condition: unknown, msg?: string): asserts condition {
if (!condition) {
throw new Error(msg);
}
}
function processPerson(person?: Person) {
assert(person, 'Person must be defined');
// person is now of type Person
assert(typeof person.name === 'string', 'Person must have a name');
// person.name is now of type string
console.log(person.name.toUpperCase());
}
assert returns the never type, which signals to the compiler that code execution halts on a false condition.
assert.
unknown type, which allows the compiler to infer types after a check.
asserts condition return type, which acts as an assertion function for control flow analysis.
54
What is the type of Keys in the snippet below?
typescript
type A = { a: string; common: number };
type B = { b: string; common: string };
type Keys = keyof (A | B);
'a' | 'b' | 'common'
'common'
'a' | 'b'
never
55
What is the primary reason the following code produces a compile-time error?
typescript
function createInstance<T>(constructor: { new(): T }): T {
return new constructor();
}
class MyClass {
private name: string;
constructor() { this.name = 'instance'; }
}
// Error occurs on the line below
const instance = createInstance(MyClass);
private members.
{ new(): T } does not match MyClass because it refers to the public-facing constructor, and MyClass has private instance members, which affects its structural compatibility.
createInstance function should be called with new createInstance(MyClass).
MyClass is a type, not a value, and cannot be passed as an argument.
56
You have two files, math.ts and app.ts. You want to create a single JavaScript output file bundle.js and a corresponding declaration file bundle.d.ts. Which combination of tsconfig.json settings and compiler command is most appropriate?
// tsconfig.json
{
"compilerOptions": {
"target": "es2020",
"module": "amd",
/ Add settings here /
}
}
"outFile": "./dist/bundle.js", "declaration": true and run tsc --project .. This will fail because outFile is only supported for amd and system modules.
"outFile": "./dist/bundle.js", "declaration": true and run tsc.
"outDir": "./dist", "declaration": true and run tsc app.ts math.ts --out dist/bundle.js.
"outDir": "./dist", "declaration": true and use a bundler like Webpack or Rollup, as tsc cannot bundle multiple files into one with declaration files unless using amd or system modules.
57
You want to compile your TypeScript project into a single JavaScript file named bundle.js and a corresponding bundle.d.ts. Given the tsconfig.json below, what is the outcome when running tsc?
{
"compilerOptions": {
"target": "es2020",
"module": "es2020",
"declaration": true,
"outFile": "./dist/bundle.js"
},
"include": ["src/*/.ts"]
}
dist/bundle.js is created because declaration files cannot be bundled.
dist/bundle.js and dist/bundle.d.ts.
outFile option cannot be used when the module is not None, System, or AMD.
58
What is the key difference in behavior between any and unknown in the following code, and why does one line fail to compile?
typescript
function processData(data: any, data2: unknown) {
console.log(data.property.name); // Line 1
console.log(data2.property.name); // Line 2: Compile Error
}
any effectively disables all type checking for the variable, allowing any operation. unknown is a type-safe top type that requires type assertion or narrowing before operations are permitted.
any is a top type, while unknown is a bottom type. Accessing properties on a bottom type is forbidden.
unknown causes the compiler to automatically attempt to infer a more specific type, which fails here. any does not trigger this inference.
any is inferred by the compiler when no type is provided, whereas unknown must be explicitly annotated.
59
TypeScript's type system is primarily described as "structural". What does this mean in practice, and how does it differ from a "nominal" type system?
typescript
class User {
id: number;
name: string;
}
class Product {
id: number;
name: string;
}
function printName(obj: User) {
console.log(obj.name);
}
const p = new Product();
p.id = 1;
p.name = 'Laptop';
printName(p); // Why does this work?
Product implicitly extends User.
Product instance has the same shape (or structure) of properties and types required by the User type.
type aliases, not class instances. The code has a hidden type error.
60
In the following code, what is the type of x after the switch statement, and why?
typescript
function check(value: string | number | boolean) {
let x: string | number;
switch (typeof value) {
case 'string':
x = value;
break;
case 'number':
x = value;
break;
default:
// The 'boolean' case is not handled
// What is the type of x here?
// A value must be assigned to x before it is used.
// To make this compile, let's assume it's used after the switch.
}
// return x; // This would cause an error: 'x' is possibly 'undefined'.
}
Let's refine the question. What happens if we try to use x immediately after the switch?
typescript
function check(value: string | number | boolean) {
let x: string | number;
switch (typeof value) {
case 'string': x = value; break;
case 'number': x = value; break;
}
return x; // What is the error here?
}
string | number. There is no error.
x could be unassigned.
x is never because the default case in the switch is unhandled.
boolean case doesn't assign to x.
61
Analyze the following mapped type. What is the resulting structure of EventMap?
typescript
type Route = '/users' | '/posts';
type Methods<R extends Route> = R extends '/users'
? 'GET' | 'POST'
: 'GET';
type EventMap = {
[R in Route]: {
method: Methods<R>;
handler: (req: { route: R }) => void;
}
};
{
'/users': { method: 'GET' | 'POST'; handler: (req: { route: '/users' }) => void; };
'/posts': { method: 'GET'; handler: (req: { route: '/posts' }) => void; };
}
Methods<R> cannot be resolved within the mapped type.
{
[R in Route]: { method: 'GET' | 'POST'; handler: (req: { route: R }) => void; }
}
{
'/users': { method: 'GET' | 'POST'; handler: (req: { route: '/users' | '/posts' }) => void; };
'/posts': { method: 'GET'; handler: (req: { route: '/users' | '/posts' }) => void; };
}