我是 typescript 和索引签名的新手,我不知道如何在我的代码中解决这个错误。我假设我需要在变量sortProperty上对变量sorted进行一些操作,但是我找不到答案。我有2个错误。一个在 setData(sorted) 上
类型{ id:编号;作业名称:字符串;创建日期:字符串;已修改:字符串; }[]"不能赋给类型为“SetStateAction〈never[]〉”的参数
另一个位于 (B[sortProperty]) 上
元素隐式具有“any”类型,因为“string”类型的表达式不能用于索引
data.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'
}
]
作业.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>
))}
1条答案
按热度按时间pftdvrlh1#
这里有一堆问题,它们都是相关的,当一个变量的类型不完整或不正确时,它可能会在使用该变量的其他地方引起问题。
组件的工作是排序和呈现一个任务对象数组,它内部存储了两种状态:
1.当前排序属性。
1.已排序任务的数组。
(Note:排序数组1不 * 需要 * 是一个状态,因为它是一个派生值。个人而言,我会使用
useMemo
而不是useState
和useEffect
,但您所拥有的将起作用,所以让我们保留它并专注于TypeScript问题)以下是我修复的问题:
1.描述任务对象的类型。
不是每个字符串都是有效的键,我们有一些已知的属性,仅此而已。
2.设置
data
状态的类型。它是一个任务数组,也就是
Task[]
。这里需要一个类型,因为初始值是一个类型为never[]
的空数组。如果初始数组不为空,则可以自动推断。3.将
types
对象定义为从string
到keyof Task
的Map。现在
sortProperty
具有keyof Task
类型,这意味着它始终是Task
的属性。您还可以执行以下操作:
4.删除了
AnotherStringIndexedObject
类型。排序后的数组不是一个对象,它是一个数组
Task[]
,你可以写const sorted: Task[]
,但你不需要写。5.删除了
new Date
处理。如果排序类型是
'jobName'
或'id'
,这就没有意义了。什么是new Date('MK-005478 • Spacecraft')
?对于 * 是 * 日期的字段,我们可以将ISO字符串作为字符串进行比较。6.使用lodash
sortBy
进行排序。你可以定义一个自定义的比较函数,但是我发现这真的很烦人。
7.将数据文件从
data.js
重命名为data.ts
如果是TypeScript文件,则导入的
tasks
变量将根据其值具有正确的类型。Job.tsx