Условное переключение для индексированных типов - PullRequest
0 голосов
/ 16 апреля 2020

Я хотел бы установить условие, которое срабатывает, если передаваемый тип имеет сигнатуру индекса. Пока это то, что у меня есть:

type IsIndexed<T> = T extends {[key in string]: any} ?
    "type is indexed" :
    "type is not indexed";

const a: IsIndexed<boolean> = "type is not indexed";
const b: IsIndexed<{ [key: string]: number }> = "type is indexed";
const c: IsIndexed<{ prop: string }> = "type is not indexed"; // Type '"type is not indexed"' is not assignable to type '"type is indexed"'.

Как видно из комментария, существует ошибка типа, поскольку TypeScript, похоже, рассматривает типы объектов без явной подписи индекса как подмножество тех, которые делают иметь один.

Это имеет смысл - если я пишу функцию, и все, что ей нужно для запуска, это объект с string ключами и boolean значениями, нет причины, чтобы объект, который соответствует этой форме с явно названными ключами не может быть передан в него, но для моих целей этого недостаточно.

Можно ли написать условный тип, который идентифицирует подписи индекса иначе, чем ключи с явно именованными

1 Ответ

2 голосов
/ 16 апреля 2020

Да, вы можете сделать это, проверив, является ли string подтипом keyof T для типа T. Если это так, то все строки являются действительными ключами; если нет, то ключи ограничены ограниченным набором имен ключей.

type Indexed = { [k: string]: number };
type NotIndexed = { x: number, y: number };

type Detect<T> = string extends keyof T ? 'Indexed' : 'Not Indexed';

type TestIndexed = Detect<Indexed>; // 'Indexed'
type TestNotIndexed = Detect<NotIndexed>; // 'Not Indexed'

Playground Link

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