Аргумент типа 'T' не может быть назначен параметру типа 'string'

Я реорганизую код JS в TS (на самом деле jsx / tsx), и у меня возникла проблема с функциями.

Чтобы упростить проблему ... предположим, я получил эту функцию checkIt, которая может принимать строку или число в качестве параметра и возвращать логическое значение.

Это функция JS:

const FIRST_ROW = 'Initial';
const SECOND_ROW = new Set([1, 2, 3, 4]);

const checkIt = id => {
if (FIRST_ROW.includes(id) || SECOND_ROW.includes(id)) {
    return true;
  }
  return false;
}

Вот мое испытание ... (поскольку я изучаю TS, мне нравится объявлять предполагаемые переменные согласованными)

const FIRST_ROW: string = 'Initial';
const SECOND_ROW: Set<number> = new Set([1, 2, 3, 4]);

const checkIt = <T,>(id: T): boolean => {
  if (FIRST_ROW.includes(id) || SECOND_ROW.includes(id)) {
    return true;
  }
  return false;
}

Это вызывает у меня ошибку в моих ссылках на идентификатор внутри функции: Аргумент типа 'T' не может быть назначен параметру типа 'string' (или 'number') . Я пробовал использовать выражение функции, строку Union | номер (как описано здесь), различные формы написания обобщений и перегрузок (например, здесь, и я просто не могу это сделать Работа.

Любая помощь здесь ?? Спасибо!


person Анна    schedule 23.04.2021    source источник


Ответы (1)


Как насчет использования преобразования типов? Просто намекните компилятору:

const FIRST_ROW: string = 'Initial';
const SECOND_ROW: Set<number> = new Set([1, 2, 3, 4]);

const checkIt = (id: string | number): boolean => {
  if (FIRST_ROW.includes(id as string) || SECOND_ROW.has(id as number)) {
    return true;
  }
  return false;
}

площадка

Кроме того, Set не имеет метода include.

Чтобы сделать его полностью подходящим, сначала проверьте, действительно ли это строка. Поскольку вы используете объединение string|number, компилятор знает, что если typeof id === 'string' возвращает false, тогда id должно быть number, поэтому приведение типов не требуется:

const FIRST_ROW: string = 'Initial';
const SECOND_ROW: Set<number> = new Set([1, 2, 3, 4]);

const checkIt = (id: string | number): boolean =>
  typeof id === 'string' ? FIRST_ROW.includes(id) : SECOND_ROW.has(id)
;

площадка

person Poul Kruijt    schedule 23.04.2021
comment
Большой! Спасибо. Что касается Set.includes, при записи здесь произошла ошибка. ???? - person Анна; 23.04.2021
comment
Один вопрос, хотя @Poul ... Нормально ли в TS использовать множество typeof для ограничения типов? Я видел в документации его использование, но для меня это звучало неестественно, так как казалось, что я переполняю свой код большим количеством текста и логики, которых можно было бы избежать другим способом, более простым и элегантным ... - person Анна; 23.04.2021
comment
@ Анна, если у вас есть параметр объединения, то обязательно проверьте перед тем, как делать :) - person Poul Kruijt; 23.04.2021