Отсутствие подписи типа начиная с TypeScript 2.7 - PullRequest
0 голосов
/ 31 мая 2018

Эта часть работает в TypeScript 2.6:

function resolver<Key extends keyof HashType>(a: Command<Key>): HashType[Key]['out'] {
  return handlers[a.kind](a);
}


const handlers: {[k in keyof HashType]: (arg: Command<k>) => HashType[k]['out']} = {
  a: arg => 1,
  b: arg => ''
};

type Command<Key extends keyof HashType> = HashType[Key]['in'] & { kind: Key }


type HashType = {
  a: { in: { someString: string }, out: number }
  b: { in: { someNumber: number }, out: string }
}

Однако, поскольку 2.7, она завершается с:

TS2349: Невозможно вызвать выражение, тип которого не требует вызоваподпись.Тип '((arg: Command <"a">) => число) |((arg: Command <"b">) => string) 'не имеет совместимых подписей вызовов.

Вот то же самое на детской площадке.

1 Ответ

0 голосов
/ 31 мая 2018

Я не очень разбираюсь в том, почему это работает в TypeScript 2.6, но причина, по которой это не удается сейчас, заключается в том, что компилятор защищает вас от чего-то маловероятного, и в любом случае не достаточно умен, чтобы понять, чтотип handlers[a.kind] соотносится с a.

Рассмотрим следующий допустимый, но неприятный код:

const resolved = resolver<"a" | "b">({ someString: "whoops", kind: "b" });

Поскольку Key extends keyof HashType, Key может быть равно до keyof HashType.И обратите внимание, что данный аргумент является Command<keyof HashType>, даже если это не Command<"a"> или Command<"b">.Компилятор не может гарантировать, что handlers[a.kind] будет применяться к a.

Может ли это быть проблемой при реальном использовании кода?Возможно нет.Если нет, вы можете утверждать, что знаете больше, чем компилятор, и используете утверждение типа :

function resolver<Key extends keyof HashType>(a: Command<Key>): HashType[Key]['out'] {
  const handler = handlers[a.kind] as (arg: Command<Key>) => HashType[Key]['out'];
  return handler(a);
}

Теперь код успешно компилируется.Если вы беспокоитесь о том, что кто-то передаст слишком широкий аргумент в код, есть способы обойти это.Но это, вероятно, не стоит того.

Надеюсь, это поможет!По аналогичной проблеме смотрите этот вопрос .

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