tezvyn:

Implement a generic PickByType<T, U> utility type

AI-drafted, machine-checkedSource: typescriptlang.orgadvanced

Tests mapped-type key filtering via conditional types and as remapping. Great answer: [K in keyof T as T[K] extends U ? K : never]: T[K]. Red flag: mapping all keys and setting values to never, which preserves keys instead of removing them.

WHAT THIS TESTS: Your fluency with TypeScript type-level programming, specifically combining mapped types, conditional types, and the as key-remapping clause introduced in TypeScript 4.1. The interviewer wants to see if you can transform an object type based on property value constraints rather than just key names, which is a common pattern in utility libraries and API typing.

A GOOD ANSWER COVERS: First, the modern syntax using key remapping: type PickByType<T, U> = { [K in keyof T as T[K] extends U ? K : never]: T[K] }. Second, an explanation of the conditional check: T[K] extends U evaluates whether the property type is assignable to U, meaning string extends string | number is true, but string | boolean extends string | number is false. Third, a brief mention of the pre-4.1 workaround if relevant: creating a helper mapped type that maps matching keys to K and others to never, then indexing into it with keyof T to extract the valid key union before passing it to Pick. Fourth, a discussion of edge cases such as optional properties and readonly modifiers, noting that the mapped type preserves them automatically.

COMMON WRONG ANSWERS: Mapping over keys without the as clause and setting non-matching values to never, which produces an object with never values instead of removing keys entirely. Using Extract or Exclude on keyof T, which operates on keys rather than value types. Writing T extends U ? ... which distributes over T itself instead of checking each property type. Forgetting that T[K] is the property type while K is the key, leading to backwards conditionals like U extends T[K].

LIKELY FOLLOW-UPS: How would you change the utility to pick properties that overlap with U rather than being assignable to U? What happens when T contains an index signature? How would you implement the inverse OmitByType, and does it require special handling for optional keys? Can you write this without the as clause, and why was that clause added to the language?

ONE CONCRETE EXAMPLE: Given type Data = { name: string; age: number; active: boolean; metadata: string | boolean; }, the type PickByType<Data, string | number> evaluates to { name: string; age: number; }. The metadata property is excluded because string | boolean is not assignable to string | number. If you had used an intersection check instead of extends, metadata might be included depending on the desired semantics, which is why interviewers often probe whether you understand assignability versus overlap.

Read the original → typescriptlang.org

Get five bites like this every day.

Tezvyn delivers a daily feed of 60-second tech bites with quizzes to lock in what you learn.