Checkpoint: Typed Pluck

The Course
•
3 min read

Build pluck(records,key), returning one property from each record. The input may be readonly. The chosen key must belong to the record type, and the output element type must match that specific property.

The algorithm is a simple map; the learning task is expressing its relationship without any or assertions. Use T for the record type, K constrained to keyof T, and T[K] for each returned element.

Test title and pages separately on the same book list. A title result should support string operations; pages should support numeric operations. An arbitrary missing key should fail before execution. Empty input still returns an empty list, but may need an explicit element type when inference has no records to inspect.

Predict, run, and explain

Write the output and trace the important state changes before checking it. Then run the program. Use Check types first; execution is allowed only when the real compiler accepts the source.

Predict, then runTypeScript
type Book = {
  title: string;

  pages: number;
};

type PageCount = Book["pages"];

const count: PageCount = 120;

console.log(count + 1);

Enable JavaScript to edit and type-check this example.

Check your prediction
121

Acceptance cases before you code

Write a small test plan before implementing pluck result relationships. These cases extend the brief; they are not a second worked solution. Predict the expected behavior independently, then test through the public function. A good ordinary example and a good boundary example should catch different possible mistakes.

Case to tryWhat your result should demonstrate
Title keyInfer string elements and preserve row order
Pages keyInfer numeric elements and preserve zero
Invalid key at a call siteReject during checking rather than returning a broad value union

After the core task passes, deliberately break one rule and identify the case that notices it. Restore the implementation and explain the failure in terms of the contract, not the number of assertions. If a case requires a concept you have not recalled, revisit the relevant lesson before opening the solution.

Your turn

Exercise

Checkpoint: Typed Pluck: practise

Implement pluck<T,K extends keyof T>(records:readonly T[],key:K):T[K][]. For two books, print A,B for titles and 30 for the sum of pages [10,20]. Do not broaden every output into a string|number union.

Your workspaceTypeScript
// The selected key is one generic value shared by every record in this call.

Enable JavaScript to edit and type-check this example.

Hint 1: the idea

Array.map can preserve the indexed property type directly.

Hint 2: a first step

Use record[key] in the callback.

Show one solution
One possible solutionTypeScript
function pluck<T, K extends keyof T>(records: readonly T[], key: K): T[K][] {
  return records.map(record => record[key]);
}

const books = [
  { title: "A", pages: 10 },
  { title: "B", pages: 20 }
];

console.log(pluck(books, "title").join(","));

let total = 0;

for (const pages of pluck(books, "pages")) {
  total += pages;
}

console.log(total);

Enable JavaScript to edit and type-check this example.

A,B
30

Explain why the implementation meets the stated contract. Which part is enforced by the language or checker, and which part needs behavioral evidence?

Change it and test it

Test an empty typed Book list, reject a missing key and attempt to push text into the page-count output. Explain why the compiler can give a precise return type for a literal key but may need a union for a variable that can hold different keys.

Was this article helpful?

Your response is saved on this device.