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的“饼图”数据类型不兼容。在这种情况下,我使用“任何”数据类型来使其兼容。
现在,我该如何解决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的“饼图”数据类型不兼容。在这种情况下,我使用“任何”数据类型来使其兼容。