All quizzesHard
OOP Architecture — Series 2
Preview — 3 of 10 questions
javascript
interface Repository<T> {
findById(id: string): T | undefined;
save(item: T): void;
}
abstract class BaseRepository<T> implements Repository<T> {
protected items = new Map<string, T>();
findById(id: string): T | undefined {
return this.items.get(id);
}
abstract save(item: T): void;
}
class UserRepo extends BaseRepository<{ id: string; name: string }> {
save(item: { id: string; name: string }): void {
this.items.set(item.id, item);
}
}ACompiles fine — BaseRepository is allowed to implement Repository<T> only partially: it concretely provides findById, while leaving save declared abstract; UserRepo completes the contract by implementing save, so the full chain (BaseRepository + UserRepo) together satisfies Repository<T>
BCompile-time error on BaseRepository — an abstract class can't implements an interface unless it concretely provides every one of that interface's members itself
CCompiles fine, but UserRepo also needs to redeclare findById, since inherited concrete methods don't count toward interface satisfaction
DRuntime error: Repository<T> isn't considered fully implemented until save is actually invoked at least once
javascript
abstract class Comparable<T extends Comparable<T>> {
abstract compareTo(other: T): number;
lessThan(other: T): boolean {
return this.compareTo(other) < 0;
}
}
class Version extends Comparable<Version> {
constructor(public major: number) { super(); }
compareTo(other: Version): number { return this.major - other.major; }
}
const v1 = new Version(1);
const v2 = new Version(2);
console.log(v1.lessThan(v2));ACompile-time error — Comparable<T extends Comparable<T>> is a self-referential generic constraint, which TypeScript doesn't allow
BCompiles fine, but lessThan accepts any Comparable<T> subtype as its argument, not specifically a Version — defeating the purpose of the self-referential constraint
CRuntime error: compareTo is abstract and can't actually be invoked from inside lessThan
DCompiles fine — T extends Comparable<T> ("F-bounded polymorphism") constrains T to only be a type that is itself a Comparable of itself; Version extends Comparable<Version> satisfies exactly that, so lessThan correctly requires another Version specifically (not an arbitrary Comparable<unknown>), giving fully type-safe comparisons; v1.lessThan(v2) compiles fine and logs true
javascript
class Money {
constructor(private cents: number) {}
[Symbol.toPrimitive](hint: string): string | number {
if (hint === 'number') return this.cents / 100;
if (hint === 'string') return `$${(this.cents / 100).toFixed(2)}`;
return this.cents;
}
}
const price = new Money(1999);
console.log(+price);
console.log(`${price}`);ABoth lines throw a runtime error, since classes can't customize how they're coerced to a primitive
BBoth lines log the same value, 1999, since the hint parameter passed to Symbol.toPrimitive is ignored by the JavaScript runtime
C+price triggers the 'number' coercion hint, logging 19.99; the template literal ${price} triggers the 'string' hint, logging '$19.99' — implementing [Symbol.toPrimitive] lets a class precisely define how it converts to a primitive value in each different context
DCompile-time error — [Symbol.toPrimitive] isn't a recognized well-known symbol in TypeScript's built-in type definitions
Sign up free to play
Answer all 10 questions (7 more), see explanations for every answer, and track your score.