简体   繁体   English

Typescript 索引签名错误:类型错误:类型参数不可分配给“SetStateAction”类型的参数<never[]> '</never[]>

[英]Typescript index signature error : Type error: Argument of type is not assignable to parameter of type 'SetStateAction<never[]>'

I'm new to typescript and to Index signatures and I don't find how to solve that error in my code.我是 typescript 和索引签名的新手,我找不到如何解决我的代码中的错误。 I assume that I need to something like on variable sortProperty on the variable sorted, but I can't find the answer.我假设我需要对变量排序的变量 sortProperty 之类的东西,但我找不到答案。 I have 2 errors.我有 2 个错误。 One on the setData(sorted)一个在setData(sorted)

Argument of type { id: number;类型参数 { id: number; jobName: string;职位名称:字符串; created: string;创建:字符串; modified: string;修改:字符串; }[]' is not assignable to parameter of type 'SetStateAction<never[]>' }[]' 不可分配给类型为“SetStateAction<never[]>”的参数

and the other on (b[sortProperty])另一个在(b[sortProperty])

Element implicitly has an 'any' type because expression of type 'string' can't be used to index元素隐式具有“任何”类型,因为“字符串”类型的表达式不能用于索引

data.js数据.js

export const tasks = [
    {
      id: "1",
      jobName: 'MK-00544 • Spacecraft',
      created: '2016-09-03',
      modified: '2016-09-04'
    },
    {
      id: "2",
      jobName: 'MK-00545 • Spacecraft',
      created: '2017-09-26',
      modified: '2018-09-29'
    },
    {
      id: "3",
      jobName: 'MK-00546 • Spacecraft',
      created: '2019-10-03',
      modified: '2022-12-08'
    },
    {
      id: "4",
      jobName: 'MK-00547 • Spacecraft',
      created: '2020-09-12',
      modified: '2021-09-03'
    },
    {
      id: "5",
      jobName: 'MK-005478 • Spacecraft',
      created: '2019-09-03',
      modified: '2019-09-03'
    },
    {
      id: "6",
      jobName: 'MK-00549 • Spacecraft',
      created: '2019-09-03',
      modified: '2019-09-03'
    }
  ]

Job.tsx:作业.tsx:

 interface Task {
    [key: string]: string
  }
  const [data, setData] = useState<Task>([])
  const [sortType, setSortType] = useState('jobName')

  useEffect(() => {
    const sortArray = (type: string) => {
      interface StringIndexedObject {
        [key: string]: string
      }
      const types: StringIndexedObject = {
        jobName: 'jobName',
        created: 'created',
        modified: 'modified'
      }
      interface AnotherStringIndexedObject {
    [key: string]: keyof Task
  }
  const sortProperty = types[type]
  const sorted: AnotherStringIndexedObject = [...tasks].sort(
    (a, b) => new Date(b[sortProperty]) - new Date(a[sortProperty])
  )
      console.log(sorted)
      setData(sorted)
    }

    sortArray(sortType)
  }, [sortType])
  return (
<div className="font-bold">Sort by:</div>
            <select
              onChange={(e) => setSortType(e.target.value)}
              className="text-center px-5 bg-gray-200 rounded-xl"
            >
              <option value="id">Id</option>
              <option value="jobName">Job name</option>
              <option value="created">Newest</option>
              <option value="modified">Last modified</option>
            </select>
            <div>({tasks.length} users)</div>

   {data.map((task) => (
                <tr
                  key={task.id}
                  className="tableau text-center cursor-pointer"
                  onClick={() => router.push(`/job/${task.id}`)}
                >
                  <td className="py-3">{task.jobName}</td>
                  <td className="py-3">
                    <div className="flex items-center gap-5 justify-center">
                      {task.created}
                    </div>
                  </td>
                  <td className="py-3">
                    <div className="flex items-center gap-5 justify-center">
                      {task.modified}
                    </div>
                  </td>
              ))}

You've got a bunch of issues here which are all related.你在这里遇到了一堆问题,这些问题都是相关的。 When the type for one variable is incomplete or incorrect it can cause issues in other places where you use that variable.当一个变量的类型不完整或不正确时,它可能会导致您使用该变量的其他地方出现问题。

Your component's job is to sort and render an array of task objects.您的组件的工作是排序和呈现一组任务对象。 It internally stores two states:它内部存储两种状态:

  1. The current sort property.当前排序属性。
  2. The array of sorted tasks.已排序任务的数组。

(Note: the sorted array one doesn't need to be a state as it is a derived value. Personally I would use a useMemo instead of a useState and a useEffect but what you have will work so let's keep it and focus on the TypeScript issues) (注意:排序后的数组不需要是 state,因为它是派生值。就我个人而言,我会使用useMemo而不是useStateuseEffect ,但你所拥有的将起作用,所以让我们保留它并专注于 TypeScript问题)

Here are the things that I've fixed:以下是我已修复的问题:

1. Describe the type of a task object. 1.描述任务类型object。

Not every string is a valid key here.并非每个字符串都是此处的有效键。 We have a few known properties and that's it.我们有一些已知的属性,仅此而已。

interface Task {
    id: string;
    jobName: string;
    created: string;
    modified: string;
}

2. Set a type for the data state. 2.为data state设置类型。

It is an array of tasks aka Task[] .它是一组任务,又名Task[] You need a type here because the initial value is an empty array which has type never[] .您在这里需要一个类型,因为初始值是一个类型为never[]的空数组。 If the initial array was not empty then it could be inferred automatically.如果初始数组不为空,则可以自动推断。

const [data, setData] = useState<Task[]>([])

3. Defined your types object as mapping from string to keyof Task . 3. 将types object 定义为从stringkeyof Task的映射。

Now the sortProperty has the type keyof Task , meaning that it is always a property of the Task .现在sortProperty的类型为keyof Task ,这意味着它始终是Task的属性。

const sortArray = (type: string) => {
    interface StringIndexedObject {
        [key: string]: keyof Task
    }
    const types: StringIndexedObject = {
        jobName: 'jobName',
        created: 'created',
        modified: 'modified'
    }
    const sortProperty = types[type];

You can also do:你也可以这样做:

const types: Record<string, keyof Task> = {

4. Removed the AnotherStringIndexedObject type. 4. 删除了AnotherStringIndexedObject类型。

The sorted array is not an object. It is an array Task[] .排序后的数组不是 object。它是一个数组Task[] You can write const sorted: Task[] , but you don't need to.您可以编写const sorted: Task[] ,但您不需要。

5. Removed the new Date handling. 5.删除了new Date处理。

This doesn't make sense if the sort type is 'jobName' or 'id' .如果排序类型是'jobName''id'则这没有意义。 What is new Date('MK-005478 • Spacecraft') ?什么是new Date('MK-005478 • Spacecraft') For the fields which are dates, we can compare the ISO strings as strings.对于日期字段,我们可以将 ISO 字符串作为字符串进行比较。

6. Used lodash sortBy for the sorting. 6. 使用lodash sortBy进行排序。

You can define a custom compare function but I find this really annoying.您可以定义一个自定义比较 function但我觉得这真的很烦人。

const sorted = sortBy(tasks, sortProperty);

7. Renamed your data file from data.js to data.ts 7. 将数据文件从data.js重命名为data.ts

If it is a TypeScript file then your imported tasks variable will have proper types based on its values.如果它是一个 TypeScript 文件,那么您导入的tasks变量将根据其值具有适当的类型。


Job.tsx作业.tsx

import React, { useState, useEffect } from 'react';
import { sortBy } from 'lodash';
import { useRouter } from 'next/router';
import { tasks } from './data';

export interface Task {
    id: string;
    jobName: string;
    created: string;
    modified: string;
}

export const Job = () => {
    const router = useRouter();

    const [data, setData] = useState<Task[]>([])
    const [sortType, setSortType] = useState('jobName')

    useEffect(() => {
        const sortArray = (type: string) => {
            interface StringIndexedObject {
                [key: string]: keyof Task
            }
            const types: StringIndexedObject = {
                jobName: 'jobName',
                created: 'created',
                modified: 'modified'
            }
            const sortProperty = types[type];
            const sorted = sortBy(tasks, sortProperty);
            console.log(sorted)
            setData(sorted)
        }

        sortArray(sortType)
    }, [sortType]);

    return (
        <div>
            <div className="font-bold">Sort by:</div>
            <select
                onChange={(e) => setSortType(e.target.value)}
                className="text-center px-5 bg-gray-200 rounded-xl"
            >
                <option value="id">Id</option>
                <option value="jobName">Job name</option>
                <option value="created">Newest</option>
                <option value="modified">Last modified</option>
            </select>
            <div>({tasks.length} users)</div>

            {data.map((task) => (
                <tr
                    key={task.id}
                    className="tableau text-center cursor-pointer"
                    onClick={() => router.push(`/job/${task.id}`)}
                >
                    <td className="py-3">{task.jobName}</td>
                    <td className="py-3">
                        <div className="flex items-center gap-5 justify-center">
                            {task.created}
                        </div>
                    </td>
                    <td className="py-3">
                        <div className="flex items-center gap-5 justify-center">
                            {task.modified}
                        </div>
                    </td>
                </tr>
            ))}
        </div>
    )
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 类型错误:“字符串”类型的参数不可分配给“SetStateAction”类型的参数<number> '?</number> - Type error: Argument of type 'string' is not assignable to parameter of type 'SetStateAction<number>'? Typescript,useContext(),错误:“never[]”类型的参数不可分配给类型参数 - Typescript, useContext(), error: Argument of type 'never[]' is not assignable to parameter of type 如何修复 React TypeScript 错误:'""' 类型的参数不可分配给 'SetStateAction 类型的参数<undefined> '</undefined> - How to fix React TypeScript error: Argument of type '""' is not assignable to parameter of type 'SetStateAction<undefined>' 类型参数不可分配给“SetStateAction”类型的参数<never[]> &#39;。 在反应中 - Argument of type is not assignable to parameter of type 'SetStateAction<never[]>'. in React “未知 []”类型的参数不可分配给“SetStateAction”类型的参数<never[]> '</never[]> - Argument of type 'unknown[]' is not assignable to parameter of type 'SetStateAction<never[]>' “void”类型的参数不可分配给“SetStateAction”类型的参数<never[]> '.ts(2345)</never[]> - Argument of type 'void' is not assignable to parameter of type 'SetStateAction<never[]>'.ts(2345) React Typescript - 类型参数不可分配给“SetStateAction”类型的参数<user | record<string, never> >'</user> - React Typescript - Argument of type is not assignable to parameter of type 'SetStateAction<User | Record<string, never>>' Typescript/React-Native:'string | 类型的参数 null' 不可分配给“SetStateAction”类型的参数<never[]> '</never[]> - Typescript/React-Native: Argument of type 'string | null' is not assignable to parameter of type 'SetStateAction<never[]>' &#39;x&#39;类型的React Typescript参数不可分配给&#39;SetStateAction&#39;类型的参数<x]> &#39; - React Typescript Argument of type 'x' is not assignable to parameter of type 'SetStateAction<x]>' “响应”类型的参数不可分配给“SetStateAction”类型的参数 - Argument of type 'Response' is not assignable to parameter of type 'SetStateAction`
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM