Невозможно понять семантику keyof в TypeScript - PullRequest
0 голосов
/ 11 января 2020

У меня есть следующий простой пример, где объявляется K extends keyof T, но результат типа возвращаемого значения для findMember отличается, я действительно не понимаю, почему есть такая разница.

Я также создал ссылку на TypeScript Playground ЗДЕСЬ

class Group1<T> {
    findMember<K extends keyof T = keyof T>(name: K): T[K] {
        return {} as T[K];
    }
}

class Group2<T, K extends keyof T = keyof T> {
    findMember(name: K): T[K] {
        return {} as T[K];
    }
}

interface Person {
    firstName: string;
    lastName: string;
    age: number;
    addresses: Array<{
        street: string;
        city: string;
        zip: string;
    }>
}

const group1 = new Group1<Person>();
// Inferred type is Array<{ street: string; city: string; zip: string; }>;
const addresses1 = group1.findMember('addresses');

const group2 = new Group2<Person>();
// Inferred type is string | number | Array<{ street: string; city: string; zip: string; }>;
const addresses2 = group2.findMember('addresses');

1 Ответ

2 голосов
/ 11 января 2020

В group1.findMember('addresses'), K может быть выведено как "addresses", поэтому возвращается Person["addresses"].

В group2.findMember('addresses'), K является параметром типа из класса верхнего уровня декларация. Используется тип по умолчанию keyof T (все ключи T), поскольку вы не указали K, когда экземпляр был создан с помощью const group2 = new Group2<Person>();. Таким образом, вы получите возвращаемый тип Person["firstName" | "lastName" | "age" | "addresses"], который представляет собой объединение всех возможных значений свойств.

Если вы используете const group2 = new Group2<Person, "addresses">(), результаты должны совпадать.

...