сузить сопоставленные типы значений типов - PullRequest
1 голос
/ 09 апреля 2020

Вариант использования следующий:

Во-первых, у меня есть интерфейс с именем Test1, который сопоставляет определенный ключ и тип. Затем у меня есть второй интерфейс, Test2, который сопоставляет те же ключи и разные типы. В-третьих, у меня есть функции (как значения в mapper объекте), которые знают, как отображать между первым и вторым.

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

Следующий код

interface Test1 {
  a: number;
  b: string;
}

interface Test2 {
  a: object;
  b: Array<number>;
}

type Mapper = {
  [P in keyof Test1]: (param: Test2[P]) => Test1[P];
};

const mapper: Mapper = {
  a: (param: object) => 123,
  b: (param: Array<number>) => 'asd'
};

function test<T extends keyof Test1>(type: T, msg: Test2[T]): Test1[T] {
  const func = mapper[type];
  return func(msg);
}

выдает следующее исключение при попытке передать msg до func:

Argument of type `Test2[T]` is not assignable to parameter of type `number[]`.

В этом примере предположим, что type будет равно 'a', тогда я хочу получить функцию, которую mapper содержит в качестве значения ключа 'a' и используйте его на msg У меня есть.

Я видел эту `проблему при поиске решения, но я подумал, что, возможно, мой случай отличается rnet, причина в том, что я использую сопоставленный тип.

Любой способ решить это? Спасибо!

1 Ответ

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

Проблема связана с тем, что тип func выводится как (param: object & number[]) => 'number | string', который сужается до (param: number[]) => 'number | string' Компилятор машинописного текста просто недостаточно умен, чтобы понять, что сигнатура параметров func всегда совпадает Test2[T].

К сожалению, ваше лучшее решение - просто привести и сообщить компилятору, что вы знаете лучше.

function test<T extends keyof Test1>(type: T, msg: Test2[T]): Test1[T] {
  const func = mapper[type] as any;
  return func(msg);
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...