TypeScript 类型转换和 D3.js 错误

TypeScript type cast & D3.js errors

现在,我该如何解决this/typecast这个问题?

import { useEffect, useState } from "react";
import { arc, pie, DSVRowArray, csv, PieArcDatum } from "d3";

const CSVURL =
  "https://gist.githubusercontent.com/mzs21/df0621d1ca5a25fa6baeeae93562c1a1/raw/CSSNamedColors.csv";

const width = 960;
const height = 500;
const centerX = width / 2;
const centerY = height / 2;

const FetchData = () => {
  const [data, setdata] = useState<DSVRowArray<string>>();

  const pieArc = arc().innerRadius(0).outerRadius(width);
  const colorPie = pie().value(1);

  useEffect(() => {
    csv(CSVURL).then(setdata); // Fetching data & updating data
  }, []);

  if (!data) {
    return <pre>loading...</pre>;
  }

  console.log(data[0]);

  return (
    <svg width={width} height={height}>
      <g transform={`translate(${centerX}, ${centerY})`}>
        {colorPie(data).map((d: PieArcDatum<number>) => (
          <path fill={d.data["RGB hex value"]} d={pieArc(d)} />
        ))}
      </g>
    </svg>
  );
};

export default FetchData;

代码执行但在 VSCode 中出现错误。图片中有VSCode的错误。

Errors of VSCode are in the picture

我也把错误贴在这里:

ERROR in src/components/FetchData/FetchData.tsx:99:19
TS2345: Argument of type 'DSVRowArray<string> | PieArcDatum<number>' is not assignable to parameter of type '(number | { valueOf(): number; })[]'.
  Type 'DSVRowArray<string>' is not assignable to type '(number | { valueOf(): number; })[]'.
    The types returned by 'pop()' are incompatible between these types.
      Type 'DSVRowString<string> | undefined' is not assignable to type 'number | { valueOf(): number; } | undefined'.
        Type 'DSVRowString<string>' is not assignable to type 'number | { valueOf(): number; } | undefined'.
          Type 'DSVRowString<string>' is not assignable to type '{ valueOf(): number; }'.
            The types returned by 'valueOf()' are incompatible between these types.
              Type 'Object' is not assignable to type 'number'.
     97 |             } */}
     98 |
  >  99 |         {colorPie(data).map((d: DSVRowArray<string> | PieArcDatum<number>) => (
        |                   ^^^^
    100 |           <path
    101 |             key={Math.random()}
    102 |             fill={d.data["RGB hex value"]}

ERROR in src/components/FetchData/FetchData.tsx:99:29
TS2345: Argument of type '(d: DSVRowArray<string> | PieArcDatum<number>) => JSX.Element' is not assignable to parameter of type '(value: PieArcDatum<number | { valueOf(): number; }>, index: number, array: PieArcDatum<number | { valueOf(): number; }>[]) => Element'.
  Types of parameters 'd' and 'value' are incompatible.
    Type 'PieArcDatum<number | { valueOf(): number; }>' is not assignable to type 'DSVRowArray<string> | PieArcDatum<number>'.
      Type 'PieArcDatum<number | { valueOf(): number; }>' is not assignable to type 'PieArcDatum<number>'.
        Type 'number | { valueOf(): number; }' is not assignable to type 'number'.
          Type '{ valueOf(): number; }' is not assignable to type 'number'.
     97 |             } */}
     98 |
  >  99 |         {colorPie(data).map((d: DSVRowArray<string> | PieArcDatum<number>) => (
        |                             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  > 100 |           <path
        | ^^^^^^^^^^^^^^^
  > 101 |             key={Math.random()}
        | ^^^^^^^^^^^^^^^
  > 102 |             fill={d.data["RGB hex value"]}
        | ^^^^^^^^^^^^^^^
  > 103 |             d={pieArc(d)!}
        | ^^^^^^^^^^^^^^^
  > 104 |           />
        | ^^^^^^^^^^^^^^^
  > 105 |         ))}
        | ^^^^^^^^^^
    106 |       </g>
    107 |     </svg>
    108 |   );

ERROR in src/components/FetchData/FetchData.tsx:102:21
TS2339: Property 'data' does not exist on type 'DSVRowArray<string> | PieArcDatum<number>'.
  Property 'data' does not exist on type 'DSVRowArray<string>'.
    100 |           <path
    101 |             key={Math.random()}
  > 102 |             fill={d.data["RGB hex value"]}
        |                     ^^^^
    103 |             d={pieArc(d)!}
    104 |           />
    105 |         ))}

ERROR in src/components/FetchData/FetchData.tsx:103:23
TS2769: No overload matches this call.
  Overload 1 of 2, '(this: any, d: DefaultArcObject, ...args: any[]): string | null', gave the following error.
    Argument of type 'DSVRowArray<string> | PieArcDatum<number>' is not assignable to parameter of type 'DefaultArcObject'.
      Type 'DSVRowArray<string>' is missing the following properties from type 'DefaultArcObject': innerRadius, outerRadius, startAngle, endAngle
  Overload 2 of 2, '(this: any, d: DefaultArcObject, ...args: any[]): void', gave the following error.
    Argument of type 'DSVRowArray<string> | PieArcDatum<number>' is not assignable to parameter of type 'DefaultArcObject'.
      Type 'DSVRowArray<string>' is not assignable to type 'DefaultArcObject'.
    101 |             key={Math.random()}
    102 |             fill={d.data["RGB hex value"]}
  > 103 |             d={pieArc(d)!}
        |                       ^
    104 |           />
    105 |         ))}
    106 |       </g>

在 CodeSandBox 中它工作正常。没有错误。游乐场:https://codesandbox.io/s/frosty-cannon-bfxprg?file=/src/FetchData.tsx:0-975

解决方案-

import { arc, csv, DSVRowArray, pie, PieArcDatum } from "d3";
import { useEffect, useState } from "react";

const CSVURL =
  "https://gist.githubusercontent.com/mzs21/df0621d1ca5a25fa6baeeae93562c1a1/raw/CSSNamedColors.csv";

const width = 960;
const height = 500;
const centerX = width / 2;
const centerY = height / 2;


const FetchData = () => {
  const [data, setdata] = useState<DSVRowArray<string>>();

  const pieArc = arc().innerRadius(0).outerRadius(width);
  const colorPie = pie().value(1);


  useEffect(() => {
    csv(CSVURL).then(setdata); // Fetching data & updating data
  }, []);

  if (!data) {
    return <pre>loading...</pre>;
  }

  return (
    <svg width={width} height={height}>
      <g transform={`translate(${centerX}, ${centerY})`}>
        {colorPie(data as any).map(         // here
          (d: PieArcDatum<number | { valueOf(): number }>) => (
            <path
              key={Math.random()}
              fill={(d.data as { [key: string]: any })[ // here
                "RGB hex value"
              ].toString()}
              d={pieArc(d as any)!} // here
            />
          )
        )}
      </g>
    </svg>
  );
};

export default FetchData;

有什么建议吗?

所以,我正在获取的数据与D3的“饼图”数据类型不兼容。在这种情况下,我使用“任何”数据类型来使其兼容。