对象是类型'未知'在React D3中设置数据时出错

发布于 2025-02-12 20:00:50 字数 1823 浏览 1 评论 0原文

我正在尝试设置一个自定义挂钩,以获取数据,对数据进行一些操纵,并在React D3应用程序中返回操纵数据。数据type

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

useeffect挂钩中有一个错误对象是'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) 

})

I am trying to set up a custom hook that fetches data, does some manipulations on the data and returns the manipulated data in a react d3 application. The data type is

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

Inside the useEffect hook there is an error 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
}

I'm a bit struggling with typescript and any help, or recommendations would be valuable.

Update

With the help of Robby Cornelissen, I made some progress and updated the code, and still some issues. So I tried updating the EventViewerDataTypes as

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

But still have some errors

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) 

})

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

So要识趣 2025-02-19 20:00:50

您的代码存在许多问题:

Untyped JSON响应

,打字稿编译器无法从jsonurl中推断出哪种类型。

根据 json()函数具有 norfollow noreferrer“> eneric bentic presencip 这应该修复它:

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

处理未定义的 JSON响应,

因为从类型定义中看来json()函数还可以返回undefined,您可能还需要使用可选链接操作员(或一个如果 -Check)在通过data循环之前:

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

如果setData(data)(data)函数您在不接受undefined <函数/code>,如果 check以及调用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&lt; EventViewerDatatype&gt; [])到您的模型对象(event> eventviewerdatatatepe [] [])。

There are a number of issues with your code:

Untyped JSON response

There is no way for the TypeScript compiler to infer what type will be retrieved from the jsonUrl.

According to the type definition, the json() function has a generic constraint that lets you specify the expected return type, so this should fix it:

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

Handling of an undefined JSON response

Since from the type definition it seems that the json() function can also return undefined, you might also need to use the optional chaining operator (or an if-check) before looping over data:

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

In case the setData(data) function you call after doesn't accept undefined, you're probably better off with an explicit if-check and either calling setData(null) or not calling setData() at all.

Discrepancies between JSON types and model types

There are discrepancies between the JSON data you retrieve, and the way you wish to model them in your application. First of all, it's more readable and convenient to type a single EventViewerDataType object (instead of EventViewerDataTypes), and then use EventViewerDataType[] whenever you need an array.

Based on your processing logic, this is how I think EventViewerDataType should be typed:

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

Then, since your JSON seems to contain only strings, I would use a mapped type to define the data transfer object as:

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

Then, in your processing logic, instead of using forEach(), use map() to map from your JSON format objects (StringValues<EventViewerDataType>[]) to your model objects (EventViewerDataType[]).

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文