K extends keyof T là generic constraint — nó ràng buộc tham số kiểu K chỉ được là key thật của T, nhờ đó vừa chặn key sai lúc biên dịch, vừa để kiểu trả về mô tả đúng object con.
function pick<T extends object, K extends keyof T>(obj: T, keys: K[]): Pick<T, K> {
const out = {} as Pick<T, K>
for (const k of keys) out[k] = obj[k]
return out
}
const user = { id: 1, name: 'An', email: 'a@b.c' }
const small = pick(user, ['id', 'name']) // { id: number; name: string }
pick(user, ['phone']) // error: 'phone' không phải keyofNếu bỏ constraint:
- K là string thì obj[k] lỗi vì không index được vào T.
- Kiểu trả về đành để Partial<T> hoặc any — nơi gọi mất autocomplete và mất luôn thông tin field nào chắc chắn tồn tại.
Ba điểm cần nói khi phỏng vấn:
- Constraint là "yêu cầu tối thiểu" của tham số kiểu, không phải ép về đúng kiểu đó.
- TypeScript suy luận K từ mảng truyền vào (['id', 'name'] → 'id' | 'name'), nên không phải viết type argument bằng tay.
- keys: K[] giữ liên kết giữa đầu vào và đầu ra; nếu khai báo keys: string[] thì liên kết đó biến mất.