对象类型为 'unknown' 在 react d3 中设置数据时出错



我试图建立一个自定义钩子,获取数据,对数据进行一些操作,并在react d3应用程序中返回被操纵的数据。数据type

interface EventViewerDataTypes {
date: string
site: string
type: string
value: string
}[]

useEffect钩子里面有一个错误Object is of type 'unknown'.

import { useState, useEffect } from "react"
import { json, timeParse } from "d3"
const parseTime = timeParse("%d-%m-%Y")
interface EventViewerDataTypes {
date: string
site: string
type: string
value: string
}[]
export const useData = (jsonUrl: string) => {
const [data, setData] = useState<EventViewerDataTypes | null>(null)
useEffect(() => {
json(jsonUrl).then((data) => {
data.forEach((d) => {
d.date = parseTime(d.date)
d.value = +d.value
})
setData(data)
})
}, [])
return data
}

我有点纠结于typescript和任何帮助,或建议将是有价值的。

Robby Cornelissen的帮助下,我取得了一些进展并更新了代码,但仍然存在一些问题。所以我尝试将EventViewerDataTypes更新为

interface EventViewerDataTypes {
date: string | Date | null
site: string
type: string
value: string | number
}[]

但仍有一些错误

json<EventViewerDataTypes[]>(jsonUrl).then((data) => {
data?.forEach((d) => {
// Error!
d.date = parseTime(d.date) 
// Argument of type 'string | Date | null' is not assignable to parameter of type 'string'. Type 'null' is not assignable to type 'string'
d.value = +d.value
})
// Error!
//Argument of type 'EventViewerDataTypes[] | undefined' is not assignable to parameter of type 'SetStateAction<EventViewerDataTypes | null>'
setData(data) 
})

你的代码有很多问题:

无类型JSON响应

TypeScript编译器无法推断出将从jsonUrl中检索到什么类型。

根据类型定义,json()函数有一个泛型约束,允许您指定预期的返回类型,因此这应该修复它:

json<EventViewerDataTypes>(jsonUrl).then((data) => {
/* ... */
});

undefinedJSON响应的处理

由于从类型定义来看,json()函数似乎也可以返回undefined,因此您可能还需要在循环data之前使用可选的链接操作符(或if检查):

data?.forEach((d) => {
/* ... */
});

如果你之后调用的setData(data)函数不接受undefined,你可能最好使用显式的if检查,要么调用setData(null),要么根本不调用setData()

JSON类型与模型类型差异

在您检索的JSON数据和您希望在应用程序中对其建模的方式之间存在差异。首先,输入单个EventViewerDataType对象(而不是EventViewerDataTypes),然后在需要数组时使用EventViewerDataType[],这样更具可读性和便利性。

根据你的处理逻辑,我认为EventViewerDataType应该是这样输入的:

interface EventViewerDataType {
date: Date | null;
site: string;
type: string;
value: number;
}

然后,由于JSON似乎只包含字符串,我将使用映射类型来定义数据传输对象:

type StringValues<T> = {
[K in keyof T]: string;
}

然后,在您的处理逻辑中,而不是使用forEach(),使用map()从JSON格式对象(StringValues<EventViewerDataType>[])映射到您的模型对象(EventViewerDataType[])。

最新更新