TypesScript: почему keyof {} никогда не имеет тип? - PullRequest
1 голос
/ 27 апреля 2020

Меня смущает оператор keyof при применении к пустому объекту. Пример кода:

const o = {};
const k : Array<keyof typeof o> = [];
// k has type never[]

Почему тип never? Я думал, что никогда не возвращаемый тип функций, которые никогда не возвращаются. Если тип не будет any[] вместо этого?

При изменении объекта, подобного этому, тип имеет смысл:

const o = {a: 1, b: 2};
const k : Array<keyof typeof o> = []; 
// k has the type ("a" | "b")[]

Я нашел это поведение при реализации функции, которая возвращает набранные ключи объекта:

function getKeys(o: object) {
    return Object.keys(o) as Array<keyof typeof o>;
}

Функция имеет тип возврата never[], но на самом деле она должна иметь (keyof typeof o)[], если я прав

1 Ответ

1 голос
/ 27 апреля 2020

РЕДАКТИРОВАТЬ: Хорошо, так, после обновления вопросы мне понятнее. Проблема здесь в том, что вы не используете универсальные шаблоны, поэтому вы буквально запрашиваете у TS ключи object , а не SOME object .

. расположите функцию следующим образом:

function getKeys<O extends {}>(o: O) {
    return Object.keys(o) as Array<keyof O>;
}

, чтобы она принимала generi c объект типа O, и в этом случае keyof O будет напечатан точно Array<keyof O>. Например:

const keys = getKeys({ a: 1, b: 2 });
// Now keys has type ("a" | "b")[]

Старый ответ до публикации сообщения:

never представляет значение, которое никогда не может произойти, как объяснено в TS Do c. Это так, поскольку в объекте нет ключей. Чтобы понять его лучше, это утверждение из TS Do c может быть полезным:

Тип never является подтипом и присваивается каждому типу;

Это означает, что в данном случае никогда не является правильным подтипом строки, особенно это означает «без строки» и, следовательно, «без ключа».

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...