React typescript 处理动态 useState 数组数据(字符串 [] 或数字 [])

问题描述 投票:0回答:1
'use client'

import { useState } from 'react'
import { ArrowDownIcon } from '@heroicons/react/24/outline'

interface FilterGroupProps<T extends string[] | number[]> {
  title: string
  options: T // Options type depends on the value of dataType
  emitClick: (category: Record<string, T>) => void
}

const FilteringGroup = <T extends string[] | number[]>({
  title,
  options,
  emitClick,
}: FilterGroupProps<T>) => {
  const [isOpen, setIsOpen] = useState(true)
  const [checkedValues, setCheckedValues] = useState([])

  const toggle = (val: string | number) => {
    let newValues = [...checkedValues]

    if (!checkedValues.includes(val)) {
      newValues = [...checkedValues, val]
    } else {
      newValues = newValues.filter((x) => x !== val)
    }

    setCheckedValues(newValues)
  }

  return (
    <div className="m">
      {options.map((o, oi) => (
        <label key={`${o}_${oi}`} className="peer text-sm">
          <input
            type="checkbox"
            name="todo[1]"
            checked={checkedValues.includes(o)}
            onChange={() => toggle(o)}
          />
          {o}
        </label>
      ))}
    </div>
  )
}

export default FilteringGroup

选项示例:

  1. ['男','女']
  2. [8,9,10,11,12]

我是打字稿新手,我正在处理 useState 的动态数组。

该子组件将从其父组件接收一个

options
属性,格式为 pure
string[]
或 pure
number[]
。一切都工作正常,直到我想将
toggle
事件作为过滤器函数进行处理。

这行

if (!checkedValues.includes(val))
向我显示了错误

Argument of type 'string | number' is not assignable to parameter of type 'never'.
  Type 'string' is not assignable to type 'never'.

我理解初始空 [] 导致的错误,因为过滤器列表中还没有任何内容,但是我们如何根据

checkValues
类型自动初始化
x
的类型?假设如果
x
是一个字符串,那么
checkValues
应该是
string[]
,否则是
number[]

或者我是否可以将

checkValues
设置为使用动态泛型类型? 3天后找不到解决方案...

react-hooks typescript-generics react-typescript conditional-types
1个回答
0
投票

将通用

T
更改为
T extends string | number
:

interface FilterGroupProps<T extends string | number> {
  title: string
  options: T[] // Options type depends on the value of dataType
  emitClick: (category: Record<string, T>) => void
}

现在,每当您需要键入基于

T
的值时,请使用
options

const FilteringGroup = <T extends string | number>({
  title,
  options,
  emitClick,
}: FilterGroupProps<T>) => {
  const [isOpen, setIsOpen] = useState(true)
  const [checkedValues, setCheckedValues] = useState<T[]>([]) // <- array of T values

  // single T value
  const toggle = (val: T) => {
    let newValues = [...checkedValues]

    if (!checkedValues.includes(val)) {
      newValues = [...checkedValues, val]
    } else {
      newValues = newValues.filter((x) => x !== val)
    }

    setCheckedValues(newValues)
  }
© www.soinside.com 2019 - 2024. All rights reserved.