TypeScript - ההבדל בין "K extends keyof T" לבין שימוש ישיר ב-"keyof T"?


האם יש הבדל בין ההגדרות הבאות של TypeScript:

function prop<T, K extends keyof T>(obj: T, key: K) {
    return obj[key];
}

ו

function prop2<T>(obj: T, key: keyof T) {
    return obj[key];
}

אני מתכוון לא, אבל אולי פספסתי משהו. האם יש יתרונות לשימוש בגרסה הראשונה (שלעיתים קרובות משמשת במסמכים)

תשובה #1

ההבדל הוא שבמקרה הראשון סוג ההחזרה יהיה T[K] בעוד שבמקרה השני זה יהיה T[keyof T]. K יכול בהרחבה שלו להיות keyof T אך הוא יכול להיות סוג מחרוזת ספציפי שמייצג מפתח. משמעות הדבר היא שאם K הוא תכונה ספציפית, ערך ההחזרה יהיה מאותו סוג כמו התכונה:

function prop<T, K extends keyof T>(obj: T, key: K) {
    return obj[key];
}
function prop2<T>(obj: T, key: keyof T) {
    return obj[key];
}

let o = {
    p1: 0,
    p2: ''
}

let v = prop(o, 'p1') // is number, K is of type 'p1'
let v2 = prop2(o, 'p1') // is number | string, no extra info is captured