I'm beginning the process of reworking some JS apps to use the new components framework and am running into issues with TypeScript typings. The simple example shown in the docs for the Scene component shows this bit of code:
const arcgisScene = document.querySelector("arcgis-scene");
arcgisScene.addEventListener("arcgisViewReadyChange", () => {
const layer = new GraphicsLayer({ title: "My layer"});
arcgisScene.map.add(layer);
});
If I try to copy this exactly using TypeScript, my IDE (IntelliJ) can't find the arcgisScene.map property. I've installed the modules with npm, and my code looks like this:
import "@arcgis/map-components/components/arcgis-scene";
function loadMap(): void {
const arcgisScene = document.querySelector("arcgis-scene");
arcgisScene!.addEventListener("arcgisViewReadyChange", () => {
const layer = new GraphicsLayer({ title: "My layer"});
arcgisScene!.map.add(layer);
});
}
In the IDE, I can see that TS is inferring that arcgisScene is of the type HTMLArcgisSceneElement | null, but it can't find the map property.
However, if I explicitly define the type of arcgisScene as HTMLArcgisSceneElement | null, the IDE can find the map property when I hover over it, but it still gives me the "Property map does not exist on type HTMLArcgisSceneElement" error.
The app does seem to work once everything is compiled to JavaScript and bundled, but I'd like to fix the IDE errors if possible
Hi,
Your code snippets look correct – I do not see a typescript error on my side when I try this snippet.
It is possible that there is something with the typescript configuration you have.
Could you please share which configuration you are using and what exact version of @ArcGIS/map-components and typescript you have installed?
For reference, I am using the following configuration:
{
"compilerOptions": {
"allowUnreachableCode": false,
"noImplicitOverride": true,
"noImplicitReturns": true,
"noUnusedLocals": true,
"noUnusedParameters": true,
"strict": true,
"module": "esnext",
"moduleResolution": "bundler",
"resolveJsonModule": true,
"declaration": true,
"newLine": "lf",
"importHelpers": true,
"noEmitOnError": true,
"outDir": "./dist",
"allowJs": false,
"esModuleInterop": true,
"isolatedModules": true,
"experimentalDecorators": true,
"jsx": "react",
"jsxFactory": "h",
"jsxFragmentFactory": "Fragment",
"lib": [
"dom",
"dom.iterable",
"esnext"
],
"target": "es2022",
"useDefineForClassFields": false,
"skipLibCheck": false,
"noEmit": true,
"allowSyntheticDefaultImports": true,
"resolvePackageJsonExports": true,
"resolvePackageJsonImports": true,
"preserveConstEnums": true,
"noImplicitAny": true,
"noImplicitThis": true,
"strictNullChecks": true,
"strictFunctionTypes": true,
"strictBindCallApply": true,
"strictPropertyInitialization": true,
"strictBuiltinIteratorReturn": true,
"alwaysStrict": true,
"useUnknownInCatchVariables": true
},
"include": [
"src",
"*.ts"
]
}
Works fine for me, but I'm using VSCode. My module versions:
PS C:\js_react_test\map-component-sample-react> npm list --depth=0
map-components-react-sample@ C:\js_react_test\map-component-sample-react
├── @ArcGIS/core@4.32.9
├── @ArcGIS/map-components@4.32.12
├── @esri/calcite-components@3.0.3
You say it recognizes that HTMLArcgisSceneElement type exists and it shows when you hover over .map, so it's probably an IDE problem.
I would suggest updating IntelliJ and node. If your IDE uses external typescript installation to check types while you code, update that too.
I'm actually using VSCode as well but I'm using Vite@latest to setup the app initially. With that I'm actually trying to use react 19 with the web components and I'm getting similar issues as far as type issues. For instance. I'm using this code in a react component.
const handleArcgisViewReadyStateChange = (event: TargetedEvent<HTMLArcgisMapElement, void>) => {
const { portalItem } = event.target.map
console.log(portalItem.title)
}
<arcgis-map
item-id="5d2b522afda8457c9a00c4773c1648e6"
onarcgisViewReadyChange={handleArcgisViewReadyStateChange}
>
<arcgis-home position='top-left'></arcgis-home>
<arcgis-zoom position='top-left'></arcgis-zoom>
<arcgis-locate position='top-left'></arcgis-locate>
</arcgis-map>
I'm getting a typing problem with VSCode IDE telling me Property 'portalItem' does not exist on type 'Map'.
Your IDE is not lying. You are referencing a property that is not documented. Map object doesn't have many properties: Map | API Reference | ArcGIS Maps SDK for JavaScript 4.32 | Esri Developer
Map component object has more (Map | ArcGIS Maps SDK for JavaScript 4.32 | Esri Developer), but I don't see a good way to print the title of the webmap. Just ignore the error, I guess.
Thanks for following up @Edvinas_S . Here's something that I'm still trying to wrap my head around. First off, when I do the console.log for the portalItem.title, it actually gives me the title of the webmap that's in my portal. I tried giving it a name of tempProperty to see if it would still print the title. It told me tempProperty doesn't have a property called title. When I switched back to portalItem, it was indeed printing out again. I was hoping to not have to worry about IDE typing errors like this using the calcite web components. Any thoughts on that?
The other thing I had was utilizing this link for using react with the calcite components:
https://developers.arcgis.com/calcite-design-system/resources/frameworks/#calcite-components-react
Now I did read the note stating if using react 19+ we don't need to use calcite-components-react. I was hoping to get some other documentation on accessing underlying functionality in the web components so I can start writing my own components to work with the map via react.
I think you are a bit confused on how that code works. You can't just rename portalItem to anything you want
// This line means that you want to unpack a properties from event.target.map
// object into it's own variables.
// It's useful when you want to unpack many properties at once
const { portalItem } = event.target.map
// You are unpacking only one property, so it's the same as writing this
const portalItem = event.target.map.portalItem
// when you renamed portalItem to tempProperty, you basically did this
const tempProperty = event.target.map.tempProperty
// obviously this doesn't work, because there is no such thing as
// "tempProperty" inside the map object
I was hoping to not have to worry about IDE typing errors like this using the calcite web components.
map.portalItem exists in practice, but it is not documented. That means there are no definitions for this property inside the API. Because there are no definition for this property, your IDE can't possibly know it exists. And so you get a red squiggly line. Your IDE works correctly and the typing is fine.
I think this property used to be documented. They wouldn't use it in a tutorial if it was "hidden". Why it got removed, I don't know.
If you want to remove the red line, you can tell your app to ignore this warning using a decorator or create an extended type for map that includes a portalItem property.
The arcgis-map component does have a documented map property so you should be good to use it: https://developers.arcgis.com/javascript/latest/references/map-components/arcgis-map/#map
In your code sample, where is the TargetedEvent type coming from? what does it look like? does it expect event.currentTarget property to be used in place of event.target?
Try using the following type as event type instead: HTMLArcgisMapElement["arcgisViewReadyChange"].
Also, try inlining the event listener in JSX rather than having a separate function - that would remove the need for providing explicit event argument type - does that work?
Thanks for the reply @mpatiiuk !
As far as where the TargetedEvent type is coming from, it's coming from the component's on function here:
(let me know if you can't see that I can resend it)
Tried the type you gave me but no luck. still getting the same linter error of Property 'portalItem' does not exist on type 'Map'.
Inlining the listener gives me a similar error as well. I did get this code from some of the docs I found for the calcite components. It's here:
https://developers.arcgis.com/javascript/latest/tutorials/using-view-with-components/#add-script-log...
which I was sent to from this tutorial:
https://developers.arcgis.com/javascript/latest/get-started-react/#add-additional-functionality
(at the bottom of this section it mentioned going to 'this tutorial' which sends me to the previous link to this one)
I mean it does indeed log the title in the console, but I should be able to use my tooling also.
Thanks again!
I believe event.target.map is of a broad type Map, where as the .portalItem is defined on a more specific type, WebMap.
Since arcgis-map needs to work with all kind of maps, it uses the most broad type. If you know your map will be a WebMap (it will be in this case as you provided the item-id), you can cast the type manually:
// top of the file
import type WebMap from "@arcgis/core/WebMap.js";
// inside the event listener:
const { portalItem } = event.currentTarget.map as WebMap