Unit 5: TypeScript Fundamentals - 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?
string username;
let username: string;
let username = string;
let username is string;
5
Which built-in type in TypeScript can hold true or false values?
number
any
boolean
string
6 Which keyword is used to create a new name for a type, such as a union of other types?
type
interface
alias
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?
.js
.tsx
.tsc
.ts
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?
number
boolean
string
any
14
What does the type string & number resolve to?
string
never
string | number
number
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?
config.ts
package.json
typescript.json
tsconfig.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?
extends keyword.
implements keyword.
20 How would you define an array of numbers in TypeScript?
Array<number> or number[]
numbers()
[number]
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?
let data: unknown;
data = "Hello, world!";
// What happens at this line?
console.log(data.toUpperCase());
undefined.
data is unknown.
23
Which of the following statements accurately describes a key difference between interface and type aliases in TypeScript?
type aliases can be used to define union types.
interface declarations can be merged (declaration merging), while type aliases cannot.
interface can be implemented by a class.
type aliases are hoisted, but interface declarations are not.
24
Given the following types, which object is a valid instance of AdminUser?
type User = {
id: number;
name: string;
};
type Admin = {
id: number;
permissions: string[];
};
type AdminUser = User & Admin;
{ id: 1, permissions: ['write'] }
{ name: 'Bob', permissions: ['delete'] }
{ id: 1, name: 'Alice' }
{ id: 1, name: 'Alice', permissions: ['read'] }
25
What is the purpose of the extends keyword in the following generic function signature?
function getProperty<T, K extends keyof T>(obj: T, key: K) {
return obj[key];
}
T is a subclass of K.
T and K.
K must be a type that is assignable to one of the keys of T.
T.
26
Analyze the code below. What is the inferred type of the statusMessage variable?
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: true; code: number; } | { success: false; error: string; }
{ success: boolean; code: number; error: string; }
{ success: boolean; code?: number; error?: string; }
27
What is the primary effect of setting "noImplicitAny": true in the tsconfig.json file?
any type.
any types to unknown during compilation.
unknown instead of any.
any type completely throughout the project.
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)?
function processEmployee(/* employee: ??? */) {
const name = employee[0]; // should be string
const id = employee[1]; // should be number
}
Array<string | number>
{string, number}
(string | number)[]
[string, number]
29
Given the following Logger interface and FileLogger class, why does the TypeScript compiler show an error?
interface Logger {
log(message: string): void;
}
class FileLogger implements Logger {
log(message: string, level: string): void {
console.log(`[${level.toUpperCase()}] ${message}`);
}
}
log method in FileLogger has a different method signature than the one defined in the Logger interface.
log method in the interface must be marked as public.
implements Logger clause.
30
Why does the following function produce a TypeScript error?
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?
interface ApiResponse<T> {
data: T;
status: number;
}
interface User {
id: number;
username: string;
}
const response: ApiResponse<User> = { data: 'some user', status: 404 };
const response: ApiResponse = { data: { id: 1, username: 'test' }, status: 200 };
const response: ApiResponse<User> = { data: { id: 1, username: 'test' }, status: 200 };
const response: ApiResponse<User> = { data: { id: 1 }, status: 200 };
32
In the code below, what is the type of pet inside the if block?
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();
}
}
Cat | Dog
any
Dog
Cat
33
What is the primary use case for creating a type alias for a union of string literals, as shown below?
type OrderStatus = 'pending' | 'shipped' | 'delivered' | 'cancelled';
let currentStatus: OrderStatus = 'pending';
currentStatus, providing type safety and autocompletion.
OrderStatus.
currentStatus to be any string at runtime.
34
Which of the following function calls would cause a TypeScript compilation error?
function merge<T extends object, U extends object>(objA: T, objB: U) {
return { ...objA, ...objB };
}
merge({ name: 'Max' }, { age: 30 })
merge({ id: 1 }, { data: ['a', 'b'] })
merge({ name: 'Max' }, 30)
merge({ value: null }, { enabled: true })
35
Consider the following discriminated union. Why is the access to c inside the 'circle' case valid?
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;
}
}
radius is an optional property on the Shape type.
switch statement on the kind property narrows the type of s to Circle within that case block.
s to type any inside the switch statement.
36
What is the resulting type of Combined?
interface A { a: number; b: string; }
interface B { b: number; c: boolean; }
type Combined = A & B;
{ a: number; b: string | number; c: boolean; }
{ a: number; b: number; c: boolean; }
{ a: number; b: any; c: boolean; }
{ a: number; b: never; 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?
function executeCallback(callback: /* ??? */) {
callback();
}
void
() => void
(any) => any
Function
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?
// function unique(arr: ???): ??? { ... }
unique(arr: unknown[]): unknown[]
unique(arr: any[]): any[]
unique<T>(arr: T[]): T[]
unique<T>(arr: Array<T>): Array<any>
40
What happens if a class implements an interface with an optional property, but the class does not declare that property?
interface Options {
timeout?: number;
retries: number;
}
class Config implements Options {
retries: number = 3;
}
timeout is missing.
timeout property of type any to the Config class.
Config is created.
41
Consider the following TypeScript code. What is the inferred type of result?
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">.
[key] is not type-safe for creating an Omit type.
result is inferred as Partial<{ name: string; email: string; }>.
result is { name: string; email: string; }.
42
Analyze the following TypeScript function. Which statement accurately describes the type of data at the marked point?
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 narrowed to Error.
state is State, and the code compiles without error.
state is never, because all possible cases are handled in the if block.
state is of type Error, but Error is also the name of a built-in JavaScript class, causing a conflict.
43
What is the resulting type of Combined and why?
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?
interface StringMap {
[key: string]: string;
length: number;
}
length property is missing an explicit public accessor.
length property, number, is not assignable to the value type of the string index signature, string.
length is a reserved keyword and cannot be used in interfaces.
45
What is the behavior of the following conditional type IsString<T> when applied to a union type?
type IsString<T> = T extends string ? true : false;
type Result = IsString<string | number>;
Result is true, because at least one member of the union extends string.
Result is boolean, because the condition is checked for each member of the union, resulting in true | false.
Result is false, because the entire union string | number does not extend string.
46
In the context of function types, what do covariance and contravariance refer to, and which example correctly demonstrates one of them?
class Animal {}
class Dog extends Animal {}
// Which assignment is valid and why?
let processAnimal: (a: Animal) => void;
let processDog: (d: Dog) => void;
processAnimal = processDog; is valid. This is covariance, as the parameter type is more specific.
processDog = processAnimal; is valid. This is covariance, where a function can accept a more general type in place of a specific one.
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 will be missing.
dist/file.js, are generated, but the compiler exits with a non-zero status code.
dist/file.js is generated, but it contains comments indicating where the type error occurred.
48
What is the evaluated type of Result? Analyze the interaction between the mapped type and the intersection.
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; }
never
{ name: string; } | { age: number; }
49
Examine this custom type guard. Why is it considered an anti-pattern or potentially unsafe, despite compiling successfully?
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.
vehicle is Car is incorrect; it should be boolean.
instanceof Car instead of property checking.
drive property with a value of null or undefined, which would satisfy the check but not be a function.
50
What is the inferred return type of the getDeepValue function in the following example?
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');
cityName is { street: string; city: string; }.
K2 cannot be constrained by keyof T[K1].
K2.
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?
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);
(string | boolean)[]
['hello', true]
readonly ['hello', true]
[string, boolean]
52
What will be the type of config.apiKey and why does the following code behave as it does?
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);
setKey function call because myConfig's apiKey is implicitly readonly.
config.apiKey.
Config cannot override readonly apiKey with a mutable one.
config.apiKey is mutable (string) because the extending interface Config overrides the readonly modifier.
53
Consider the assert function below. After the assertion, person.name can be used as a string. What TypeScript concept makes this possible?
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.
asserts condition return type, which acts as an assertion function for control flow analysis.
unknown type, which allows the compiler to infer types after a check.
assert returns the never type, which signals to the compiler that code execution halts on a false condition.
54
What is the type of Keys in the snippet below?
type A = { a: string; common: number };
type B = { b: string; common: string };
type Keys = keyof (A | B);
'a' | 'b'
'common'
never
'a' | 'b' | 'common'
55
What is the primary reason the following code produces a compile-time error?
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);
MyClass is a type, not a value, and cannot be passed as an argument.
{ 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).
private members.
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.
"outDir": "./dist", "declaration": true and run tsc app.ts math.ts --out dist/bundle.js.
"outFile": "./dist/bundle.js", "declaration": true and run tsc --project .. This will fail because outFile is only supported for amd and system modules.
"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"]
}
outFile option cannot be used when the module is not None, System, or AMD.
dist/bundle.js and dist/bundle.d.ts.
dist/bundle.js is created because declaration files cannot be bundled.
58
What is the key difference in behavior between any and unknown in the following code, and why does one line fail to compile?
function processData(data: any, data2: unknown) {
console.log(data.property.name); // Line 1
console.log(data2.property.name); // Line 2: Compile Error
}
any is inferred by the compiler when no type is provided, whereas unknown must be explicitly annotated.
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 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.
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?
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.
type aliases, not class instances. The code has a hidden type error.
Product instance has the same shape (or structure) of properties and types required by the User type.
60
In the following code, what is the type of x after the switch statement, and why?
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.
boolean case doesn't assign to x.
x could be unassigned.
x is never because the default case in the switch is unhandled.
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' | '/posts' }) => void; };
'/posts': { method: 'GET'; handler: (req: { route: '/users' | '/posts' }) => void; };
}{
[R in Route]: { method: 'GET' | 'POST'; 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.
Did this save you a night before the exam?
LPU Notes is free, and it stays free. Ads cover part of the server bill. The rest comes out of a student's own pocket: the domain, the storage, and keeping the site up through the weeks everyone needs it at once.
The payment button didn't load. An ad blocker or a filtered network is the usual reason. to try again.
Nothing here is ever locked, and nothing unlocks. Chip in only if it was worth it. What it pays for →