react-leaflet GeoJSON with typescript - reactjs

I am pretty new using typescript with reactjs. Currently, the project I am working on is using a react-leaflet/leaflet specifically their GeoJSON component. I am running into a typescript error when I pass my data to the props.
I have been doing some research on this, even installed the geojson package and followed their examples, https://github.com/DefinitelyTyped/DefinitelyTyped/blob/master/types/geojson/geojson-tests.ts, tried everything that I know but no luck.
If I try to pass data as
const GeoJsonData: geojson.Feature<geojson.Polygon, geojson.GeoJsonProperties> = {
geometry: {
coordinates: [[
[20.7325804014456, -156.424372312952],
[20.7320799340775, -156.424348923897],
[20.732046895414, -156.425191022255],
[20.7321183621394, -156.425194200455],
[20.7321078658074, -156.425458542909],
[20.7325370751528, -156.425476608985],
[20.7325804014456, -156.424372312952]
]],
type: 'Polygon',
},
properties: {
name: 'some name'
},
type: 'Feature',
};
or
const GeoJsonData: = {
geometry: {
coordinates: [[
[20.7325804014456, -156.424372312952],
[20.7320799340775, -156.424348923897],
[20.732046895414, -156.425191022255],
[20.7321183621394, -156.425194200455],
[20.7321078658074, -156.425458542909],
[20.7325370751528, -156.425476608985],
[20.7325804014456, -156.424372312952]
]],
type: 'Polygon',
},
properties: {
name: 'some name'
},
type: 'Feature',
} as as geojson.GeoJsonObject;
I get this error
Conversion of type '{ properties: { name: string; } | { name: string; }; type: "Feature"; geometry: Polygon | null; id?: string | number | undefined; bbox?: BBox2d | BBox3d | undefined; }[]' to type 'GeoJsonObject' may be a mistake because neither type sufficiently overlaps with the other. If this was intentional, convert the expression to 'unknown' first.ts(2352)
Conversion of type '{ properties: { name: string; } | { name: string; }; type: "Feature"; geometry: Polygon | null; id?: string | number | undefined; bbox?: BBox2d | BBox3d | undefined; }[]' to type 'GeoJsonObject' may be a mistake because neither type sufficiently overlaps with the other. If this was intentional, convert the expression to 'unknown' first.
Property 'type' is missing in type '{ properties: { name: string; } | { name: string; }; type: "Feature"; geometry: Polygon | null; id?: string | number | undefined; bbox?: BBox2d | BBox3d | undefined; }[]' but required in type 'GeoJsonObject'.
But If I remove types from data. Then I get this error.
const GeoJsonData: = {
geometry: {
coordinates: [[
[20.7325804014456, -156.424372312952],
[20.7320799340775, -156.424348923897],
[20.732046895414, -156.425191022255],
[20.7321183621394, -156.425194200455],
[20.7321078658074, -156.425458542909],
[20.7325370751528, -156.425476608985],
[20.7325804014456, -156.424372312952]
]],
type: 'Polygon',
},
properties: {
name: 'some name'
},
type: 'Feature',
}
No overload matches this call.
Overload 1 of 2, '(props: Readonly<GeoJSONProps>): GeoJSON<GeoJSONProps, GeoJSON<any>>', gave the following error.
Property 'type' is missing in type '{ properties: { name: string; } | { name: string; }; type: "Feature"; geometry: Polygon | null; id?: string | number | undefined; bbox?: BBox2d | BBox3d | undefined; }[]' but required in type 'GeoJsonObject'.
Overload 2 of 2, '(props: GeoJSONProps, context?: any): GeoJSON<GeoJSONProps, GeoJSON<any>>', gave the following error.
Type '{ properties: { name: string; } | { name: string; }; type: "Feature"; geometry: Polygon | null; id?: string | number | undefined; bbox?: BBox2d | BBox3d | undefined; }[]' is not assignable to type 'GeoJsonObject'.
<Map
center={[props.centerMapCoordinates.lat, props.centerMapCoordinates.lng]}
zoom={props.centerMapCoordinates.zoom}
style={{ height: mapHeight }}
onMoveEnd={(event: any) => props.getZoomMap(event)}
>
<TileLayer url="https://server.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer/tile/{z}/{y}/{x}/"
/>
<GeoJSON
key={GeoJsonData}
data={GeoJsonData}
// data={GeoJsonData}
onEachFeature={(feature, layer) => {
layer.on('click', (e) => {
console.log(e.target.feature);
// new Field().doesIntersect(e.target.feature);
});
if (props.centerMapCoordinates.zoom > 16) {
layer.bindTooltip(feature.properties.name, {
direction: 'center',
permanent: true,
}).openTooltip();
} else {
layer.closeTooltip();
}
layer.bindPopup(feature.properties.name);
}}
/>
</Map>
Note: If I add as any to GeoJsonData it gets rid of the errors, but then does not make any sense to use typescript.
Does anyone familiar with this issue or knows how can I define geojson types?
Please let me know if you have any questions. I can provide more details if needed. Thank you in advance.

Related

TS error when passing myDecorator function as decorate prop to React Slate

I am getting the following TS error:
(property) decorate?: ((entry: NodeEntry<Node>) => BaseRange[]) | undefined
Type '([node, path]: [node: any, path: any]) => { anchor: { path: any; offset: string | number; }; focus: { path: any; offset: string; }; decoration: string; }[]' is not assignable to type '(entry: NodeEntry<Node>) => BaseRange[]'.
Type '{ anchor: { path: any; offset: string | number; }; focus: { path: any; offset: string; }; decoration: string; }[]' is not assignable to type 'BaseRange[]'.
Type '{ anchor: { path: any; offset: string | number; }; focus: { path: any; offset: string; }; decoration: string; }' is not assignable to type 'BaseRange'.
The types of 'anchor.offset' are incompatible between these types.
Type 'string | number' is not assignable to type 'number'.
Type 'string' is not assignable to type 'number'.ts(2322)
editable.d.ts(34, 5): The expected type comes from property 'decorate' which is declared here on type 'IntrinsicAttributes & { decorate?: ((entry: NodeEntry<Node>) => BaseRange[]) | undefined; onDOMBeforeInput?: ((event: InputEvent) => void) | undefined; ... 8 more ...; as?: ElementType<...> | undefined; } & TextareaHTMLAttributes<...> & MUIStyledCommonProps<...> & { ...; }'
This is happening on the decorate prop of my Editable component:
<Editable
decorate={myDecorator}
Here is a link to a codesandbox where the error is recreated on line 271:
https://codesandbox.io/s/react-typescript-forked-mwe14t?file=/src/App.tsx
index value is either string | number and offset accepts onlynumber which is why it is complaining. I needed to cast the index to number (Number(index) or +index) and then use it
const numberedIdx = Number(index);
const offsetVal = numberedIdx + urlLength;
return {
anchor: {
path,
offset: numberedIdx,
},
focus: {
path,
offset: offsetVal,
},
decoration: "link",
};

No overload matches this call in ApexCharts with React and Typescript

I'm trying to set up a chart from ApexChart in a React app made with typescript.
This is how I'm defining the options for the chart:
const options = {
chart: {
id: "lineGraph",
height: 350,
zoom: {
enabled: false
}
},
dataLabels: {
enabled: false
},
stroke: {
show: true,
curve: 'smooth',
lineCap: 'butt',
colors: undefined,
width: 2,
dashArray: 0,
},
xaxis: {
categories: [43,42,67,12,53,45,63]
}
};
const series = [
{
name: "Title",
data: [1,123,321,324,243,234,25]
}
];
And calling the chart component:
<Chart options={options} series={series} type="line"/>
However I get the error:
No overload matches this call.
Overload 1 of 2, '(props: Props | Readonly<Props>): ReactApexChart', gave the following error.
Type '{ chart: { id: string; height: number; zoom: { enabled: boolean; }; }; dataLabels: { enabled: boolean; }; stroke: { show: boolean; curve: string; lineCap: string; colors: undefined; width: number; dashArray: number; }; xaxis: { ...; }; }' is not assignable to type 'ApexOptions'.
The types of 'stroke.curve' are incompatible between these types.
Type 'string' is not assignable to type '"smooth" | "straight" | "stepline" | ("smooth" | "straight" | "stepline")[] | undefined'.
Typescript, for some reason, is not happy with putting 'smooth' on stroke.curve property. However, this is correct according to the docs. I was able to fix this by changing the type definition for ApexStroke. Originally is:
type ApexStroke = {
show?: boolean
curve?: 'smooth' | 'straight' | 'stepline' | ('smooth' | 'straight' | 'stepline')[]
lineCap?: 'butt' | 'square' | 'round'
colors?: string[]
width?: number | number[]
dashArray?: number | number[]
}
But if I put
type ApexStroke = {
show?: boolean
curve?: string
lineCap?: 'butt' | 'square' | 'round'
colors?: string[]
width?: number | number[]
dashArray?: number | number[]
}
It works but I'm not sure if this is the correct way to fix, if the package devs did something wrong or, more probably, if I did something wrong. How can I compile this without changing the type definition?
I'm not familiar whit ApexChart but here's what I've found on the docs with regards to the curve property:
stroke: {
curve: 'smooth',
// OR provide an array
curve: ['smooth', 'straight', 'stepline']
}
Perhaps the following might work?
type TCurve = 'smooth' | 'straight' | 'stepline' | 'smooth' | 'straight' | 'stepline';
type ApexStroke = {
show?: boolean;
curve?: TCurve | TCurve[];
lineCap?: 'butt' | 'square' | 'round';
colors?: string[];
width?: number | number[];
dashArray?: number | number[];
}

React Proptypes gives error while generating Proptypes for a component

I am getting an error with PropTypes.
The Props are:
type FieldTypes = 'dropdown' | 'checkbox';
type PluginDropdownData = {
label: string;
value: string;
};
type PluginManifestObject = {
label: string;
type: FieldTypes;
data: Array<PluginDropdownData> | Array<string>;
mandatory: boolean;
};
{
manifestObject: PluginManifestObject
objectKey: string;
handleValueChange: (label: string, value: string | boolean) => void;
initialValue: string | boolean;
}
This is my solution:
ComponentA.propTypes = {
manifestObject: PropTypes.shape({
label: PropTypes.string.isRequired,
type: PropTypes.oneOf(['dropdown', 'checkbox']).isRequired,
data: PropTypes.oneOfType([
PropTypes.arrayOf(PropTypes.shape({
label: PropTypes.string.isRequired,
value: PropTypes.string.isRequired,
})),
PropTypes.arrayOf(PropTypes.string),
]).isRequired,
mandatory: PropTypes.bool.isRequired,
}).isRequired,,
objectKey: PropTypes.string.isRequired,
handleValueChange: PropTypes.func.isRequired,
initialValue: PropTypes.oneOfType([
PropTypes.string,
PropTypes.bool,
]).isRequired,
};
But I am getting 2 errors:
Type 'Validator<InferProps<{ label: Validator<string>; type: Validator<string>; data: Validator<(InferProps<{ label: Validator<string>; value: Validator<string>; }> | null | undefined)[] | (string | ... 1 more ... | undefined)[]>; mandatory: Validator<...>; }>>' is not assignable to type 'Validator<PluginManifestObject>'.
Type 'InferProps<{ label: Validator<string>; type: Validator<string>; data: Validator<(InferProps<{ label: Validator<string>; value: Validator<string>; }> | null | undefined)[] | (string | ... 1 more ... | undefined)[]>; mandatory: Validator<...>; }>' is not assignable to type 'PluginManifestObject'.
Types of property 'type' are incompatible.
Type 'string' is not assignable to type 'FieldTypes'.ts(2322)
(property) manifestObject?: React.Validator<PluginManifestObject> | undefined
The above error is fixed by aleksxor answer but there is still one error, i.e.
Type 'Validator<InferProps<{ label: Validator<string>; type: Validator<"input" | "dropdown" | "checkbox" | "date" | "radio" | "range">; data: Validator<(InferProps<{ label: Validator<string>; value: Validator<...>; }> | null | undefined)[] | (string | ... 1 more ... | undefined)[]>; mandatory: Validator<...>; }>>' is not assignable to type 'Validator<PluginManifestObject>'.
Type 'InferProps<{ label: Validator<string>; type: Validator<"input" | "dropdown" | "checkbox" | "date" | "radio" | "range">; data: Validator<(InferProps<{ label: Validator<string>; value: Validator<...>; }> | null | undefined)[] | (string | ... 1 more ... | undefined)[]>; mandatory: Validator<...>; }>' is not assignable to type 'PluginManifestObject'.
Types of property 'data' are incompatible.
Type '(InferProps<{ label: Validator<string>; value: Validator<string>; }> | null | undefined)[] | (string | null | undefined)[]' is not assignable to type 'string[] | PluginDropdownData[]'.
Type '(InferProps<{ label: Validator<string>; value: Validator<string>; }> | null | undefined)[]' is not assignable to type 'string[] | PluginDropdownData[]'.
Type '(InferProps<{ label: Validator<string>; value: Validator<string>; }> | null | undefined)[]' is not assignable to type 'string[]'.
Type 'InferProps<{ label: Validator<string>; value: Validator<string>; }> | null | undefined' is not assignable to type 'string'.
Type 'undefined' is not assignable to type 'string'.ts(2322)
(property) manifestObject?: React.Validator<PluginManifestObject> | undefined
I am not sure what I am missing here. Can someone please help me with this?
Thanks
The problem is you're passing non-readonly array to the oneOf validator. And the values of non-readonly array are inferred as string type. The solution is pretty simple. Just pass it readonly tuple:
...
type: PropTypes.oneOf(['dropdown', 'checkbox'] as const).isRequired,
...
Updated answer to address the second error.
To match the type: data: Array<PluginDropdownData> | Array<string> you have to define your propTypes as:
...
data: PropTypes.oneOfType([
PropTypes.arrayOf(PropTypes.shape({
label: PropTypes.string.isRequired,
value: PropTypes.string.isRequired,
}).isRequired),
PropTypes.arrayOf(PropTypes.string.isRequired),
]).isRequired,
Notice that if you want the array to pass the validation you have to declare it's elements as isRequired. If you're not planning to make them isRequired you have to add | null | undefined to array's item type. For example those two definitions pass without error:
type PluginManifestObject = {
...
data: Array<PluginDropdownData | undefined | null> | Array<string | undefined | null>
...
}
...
data: PropTypes.oneOfType([
PropTypes.arrayOf(PropTypes.shape({
label: PropTypes.string.isRequired,
value: PropTypes.string.isRequired,
})),
PropTypes.arrayOf(PropTypes.string),
]).isRequired,
...

Array of records definition

I've got a component that uses these types and interfaces
import { FC } from 'react';
enum fieldTypes {
Text = 'Text',
DateTime = 'DateTime',
Boolean = 'Boolean',
Integer = 'Integer'
}
type Metadata = Record<string, { type: fieldTypes, widget?: string }>;
interface MetadataProperties {
metaType: string;
metadata: Array<Metadata>;
dispatchSetProperty: (properties: any) => void;
}
const MetadataComponent: FC<MetadataProperties> = ({ metaType, metadata, dispatchSetProperty }) => {...}
When I try to do
const metadata = [
{
description: {
type: fieldTypes.Text
},
},
{
title: {
type: fieldTypes.Text
}
}
];
<MetadataComponent metaType="language_metadata" metadata={metadata} dispatchSetProperty={dispatchSetProperty}/>
The last line is showing an error
TS2322: Type '({ description: { type: fieldTypes; }; title?: undefined; } | { title: { type: fieldTypes; }; description?: undefined; })[]' is not assignable to type 'Record<string, { type: fieldTypes; widget?: string | undefined; }>[]'.   Type '{ description: { type: fieldTypes; }; title?: undefined; } | { title: { type: fieldTypes; }; description?: undefined; }' is not assignable to type 'Record<string, { type: fieldTypes; widget?: string | undefined; }>'.     Type '{ description: { type: fieldTypes; }; title?: undefined; }' is not assignable to type 'Record<string, { type: fieldTypes; widget?: string | undefined; }>'.       Property 'title' is incompatible with index signature.         Type 'undefined' is not assignable to type '{ type: fieldTypes; widget?: string | undefined; }'.
I don't understand what's wrong. I've declared metadata as an Array of Metadata why is it erroring?
Any explanation would be awesome :)

Can't set columns for react data grid. Gives non assignable type error

I am new to both React and TypeScript and am trying to make a simple React Data Grid based on their simple example here: https://adazzle.github.io/react-data-grid/docs/quick-start
Here is what I have:
import React from 'react';
import ReactDataGrid from 'react-data-grid';
const columns = [
{ key: "id", name: "ID", editable: true },
{ key: "title", name: "Title", editable: true },
{ key: "complete", name: "Complete", editable: true }
];
const rows = [
{ id: 0, title: "Task 1", complete: 20 },
{ id: 1, title: "Task 2", complete: 40 },
{ id: 2, title: "Task 3", complete: 60 }
];
export const DataTable: React.FC = () => {
return (
<ReactDataGrid
columns={columns}
rowGetter={i => rows[i]}
rowsCount={rows.length}
/>
);
};
However I keep getting an error on the link where it sets the columns in the table. It says:
(JSX attribute) DataGridProps<{ [x: string]: {}; }, React.ReactText>.columns: (ColumnValue<{
[x: string]: {};
}, unknown, string> | ColumnValue<{
[x: string]: {};
}, unknown, number>)[]
Type '{ key: string; name: string; editable: boolean; }[]' is not assignable to type '(ColumnValue<{ id: number; title: string; complete: number; }, unknown, "id"> | ColumnValue<{ id: number; title: string; complete: number; }, unknown, "title"> | ColumnValue<{ id: number; title: string; complete: number; }, unknown, "complete">)[]'.
Type '{ key: string; name: string; editable: boolean; }' is not assignable to type 'ColumnValue<{ id: number; title: string; complete: number; }, unknown, "id"> | ColumnValue<{ id: number; title: string; complete: number; }, unknown, "title"> | ColumnValue<{ id: number; title: string; complete: number; }, unknown, "complete">'.
Type '{ key: string; name: string; editable: boolean; }' is not assignable to type 'ColumnValue<{ id: number; title: string; complete: number; }, unknown, "complete">'.
Types of property 'key' are incompatible.
Type 'string' is not assignable to type '"complete"'.ts(2322)
DataGrid.d.ts(6, 5): The expected type comes from property 'columns' which is declared here on type 'IntrinsicAttributes & DataGridProps<{ id: number; title: string; complete: number; }, "id" | "title" | "complete"> & { ref?: ((instance: DataGridHandle | null) => void) | RefObject<...> | null | undefined; }'
Can anyone help me parse this error? Do I need to explicitly set the type of the columns to the type that the react data grid is expecting?
I installed the react-data-grid types and the error went away:
npm install --save #types/react-data-grid

Resources