'How to convert d3.value() iterable and d3.rollup from javaScript into TypeScript
I am trying to convert this horizontal stacked bar chart code from plain javaScript into my typeScript Angular app.
When I get to this part of the code:
const series = d3
.stack()
.keys(zDomain)
.value(([, I], z: any) => {
return X[I.get(z)];
})
.order(order)
.offset(offset)(
d3.rollup(
I,
([i]) => i,
(i) => Y[i],
(i) => Z[i]
)
)
.map((s) => s.map((d) => Object.assign(d, { i: d.data[1].get(s.key) })));
I get the following compilation errors:
ERROR in app/d3.service.ts:171:15 - error TS2488: Type '{ [key: string]: number; }' must have a 'Symbol.iterator' method that returns an iterator.
171 .value(([, I], z: any) => { ~~~~~ app/d3.service.ts:176:9 - error TS2345: Argument of type 'InternMap<any, InternMap<{}, number>>' is not assignable to parameter of type 'Iterable<{ [key: string]: number; }>'. Types of property '[Symbol.iterator]' are incompatible. Type '() => IterableIterator<[any, InternMap<{}, number>]>' is not assignable to type '() => Iterator<{ [key: string]: number; }>'. Type 'IterableIterator<[any, InternMap<{}, number>]>' is not assignable to type 'Iterator<{ [key: string]: number; }>'. Types of property 'next' are incompatible. Type '(value?: any) => IteratorResult<[any, InternMap<{}, number>]>' is not assignable to type '(value?: any) => IteratorResult<{ [key: string]: number; }>'.
Type 'IteratorResult<[any, InternMap<{}, number>]>' is not assignable to type 'IteratorResult<{ [key: string]: number; }>'. Type '[any, InternMap<{}, number>]' is not assignable to type '{ [key: string]: number; }'. Index signature is missing in type '[any, InternMap<{}, number>]'.176 d3.rollup( ~~~~~~~~~~ 177 I, ~~~~~~~~~~~~ ... 180 (i) => Z[i] ~~~~~~~~~~~~~~~~~~~~~ 181 ) ~~~~~~~~~
I don't understand typeScript nor these errors well enough to understand how to typeScriptify this section of the code. Can anyone help or at least give me advice?
I have set up a minimal example of my code on StackBlitz here, but the compilation errors don't get reproduced there.
Update 11 March, 2022: Here are the versions of d3 and the d3 types that I have installed:
"@types/d3": "^7.1.0",
"d3": "^7.1.0",
And here is how I import d3 in the typescript file:
import * as d3 from "d3";
Here is a photo of all of the type errors upon compile:
Solution 1:[1]
So I think the issue here is that there is a mismatch between the @types/d3 and the d3 versions. I also moved the @types/d3 reference to devDependencies where it belongs.
This works for me on a new angular "ng new" app:
{
"name": "d3-test",
"version": "0.0.0",
"scripts": {
"ng": "ng",
"start": "ng serve",
"build": "ng build",
"watch": "ng build --watch --configuration development",
"test": "ng test"
},
"private": true,
"dependencies": {
"@angular/animations": "~13.2.0",
"@angular/common": "~13.2.0",
"@angular/compiler": "~13.2.0",
"@angular/core": "~13.2.0",
"@angular/forms": "~13.2.0",
"@angular/platform-browser": "~13.2.0",
"@angular/platform-browser-dynamic": "~13.2.0",
"@angular/router": "~13.2.0",
"d3": "7.1.0", // <!-------------- explicit 7.1.0 version
"rxjs": "~7.5.0",
"tslib": "^2.3.0",
"zone.js": "~0.11.4"
},
"devDependencies": {
"@angular-devkit/build-angular": "~13.2.5",
"@angular/cli": "~13.2.5",
"@angular/compiler-cli": "~13.2.0",
"@types/d3": "7.1.0", // <!-------------- explicit 7.1.0 version
"@types/jasmine": "~3.10.0",
"@types/node": "^12.11.1",
"jasmine-core": "~4.0.0",
"karma": "~6.3.0",
"karma-chrome-launcher": "~3.1.0",
"karma-coverage": "~2.1.0",
"karma-jasmine": "~4.0.0",
"karma-jasmine-html-reporter": "~1.7.0",
"typescript": "~4.5.2"
}
}
...and then as before, continue to use import * as d3 from 'd3';
Note that this doesn't seem to work when I make a new Stackblitz - not sure why. But here is a screenshot with the correct d3 intellisense:
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | Zze |


