React TypeScript не может отсортировать таблицу из-за того, что элемент ‘Type » не может быть присвоен типу ‘string’.ts(2345)’

#reactjs #typescript #sorting #compiler-errors

#reactjs #typescript #сортировка #ошибки компилятора

Вопрос:

У меня проблема с сортировкой таблицы в компоненте react. Проблема связана с typescript, и он выделяет аргумент и отображает ошибку следующего содержания: ‘Аргумент типа ‘ (name1: string, name2: string) => number’ не может быть присвоен параметру типа ‘(a: Element, b: Element) => number’. Типы параметров ‘name1’ и ‘a’ несовместимы. Тип ‘Element’ нельзя присвоить типу ‘string’.

Мой родительский компонент:

 const SearchWithDropdown: React.FC = () => {
  const [countries, setCountries] = useState<Array<Country>>([])
  const [value, setValue] = useState('')
  const [filteredCountries, setFilteredCountries] = useState<Array<Country>>([])
  const [isVisible, setIsVisible] = useState(false)

  const handleChange = (event: React.ChangeEvent<HTMLInputElement>) => {
    const { value } = event.target
    setValue(value)
    changeResultVisibility(value)
  }

  const changeResultVisibility = (value: string) => {
    setIsVisible(value.length >= 3)
  }

  useEffect(() => {
    const fetchMyAPI = async () => {
      let response = await fetch(url)
      const json = await response.json()
      setCountries(json)
    }
    fetchMyAPI()
  }, [])


  useEffect(() => {
    if (value.length >= 3 amp;amp; countries.length > 0) {
      setFilteredCountries(
        countries
          .filter((el: Country) => el.name.toLowerCase().includes(value))
      )
    }
  }, [value, countries])

  console.log(filteredCountries)

  return (
    <div>
      <input type="text" placeholder="Search..." value={value} onChange={handleChange}></input>
      {isVisible ? (
        filteredCountries.length > 0 ? (
          <DropdownList filteredCountries={filteredCountries} value={value} />
        ) : (
          <div>Not found!</div>
        )
      ) : null}
    </div>
  )
}
  

И дочерний компонент:

 interface DropdownListProps {
  filteredCountries: Country[]
  value: string
}

function sortData (name1: string, name2: string): number {
  name1 = name1.toLowerCase()
  name2 = name2.toLowerCase()
  return name1 > name2 ? 1 : name2 > name1 ? -1 : 0
}

const DropdownList: React.FC<DropdownListProps> = ({ filteredCountries, value }) => {
  const renderData = () =>
    filteredCountries
    .map((el) => (
      <DropdownItem key={el.name}>
        {reactStringReplace(el.name, value, (match: string, i: number) => (
          <strong key={i}>{match}</strong>
        ))}
      </DropdownItem>
    ))
    .sort(sortData)

  return <div>{renderData()}</div>
}
  

И мой файл d.ts:

 export interface Country {
  name: string
}
  

Я пытался решить, изменив объявление в файле d.ts, но это звучит немного глупо. Я новичок в TS, поэтому, возможно, мое предположение о сортировке в этом месте неверно. Возможно, это должно быть после метода filter в родительском компоненте … хм..

Большое спасибо за помощь!

Комментарии:

1. Компилятор точно сообщает вам, в чем проблема. sortData ожидает два строковых параметра, однако ваше filteredCountries.map выражение возвращает массив JSX.Element объектов, а затем вы пытаетесь отсортировать этот массив. Исходя из моей головы, я бы посоветовал вам просто попытаться переместить .sort перед .map и посмотреть, как это происходит

2. … поэтому вместо того, чтобы filteredCountries.map().sort() пытаться filteredCountries.sort().map()

3. Правильно! Спасибо! Это решило проблему 😉

Ответ №1:

Похоже, что ваша функция сортировки получает элемент, потому что вы изменяете свой массив countries с помощью метода map и возвращаете массив выпадающих элементов. Поэтому я бы посоветовал выполнить сортировку перед передачей данных компонентам DropdownItem.
Также элемент filteredCountries является объектом с именем свойства ({name: string}), поэтому ваша функция сортировки получит объект и должна извлечь из него свойство name

 function sortData (c1: Country, c2: Country): number {