#JSON import can't be assigned to type

69 messages · Page 1 of 1 (latest)

dreamy current
#

For context: I'm using react-map-gl (https://visgl.github.io/react-map-gl/), React, Vite, and typescript. I'm importing data from a json file like this:

import mapStyle from '../../assets/styles/outdoor.json';

I'm then using it in a react-map-gl Map instance (https://visgl.github.io/react-map-gl/docs/api-reference/map) like this:

<Map
  id="mainMap"
  mapStyle={mapStyle}
>
  ...
</Map>

My mapStyle should be conform to the style specification (and thus the typescript type definition) because I've generated it by using a tool. But, I'm getting a typescript error, see the message below.

The error says Types of property '"version"' are incompatible. and Type 'number' is not assignable to type '8'.. I'm not sure why this is a problem. In my json, the version field is like this:

{
  "version": 8,
  ...
}

The reason the version field is failing is probably because it's just the first field in the json file. But, why can this 8 not be assigned to number?

React component that wraps the base library's Map class (Mapbox | Maplibre). This is also the default export from react-map-gl.

dense mulch
#

it's saying the opposite, it says that number can't be assigned to 8

dreamy current
dense mulch
#

this is perhaps contravariance

#

!:vari%

craggy glacierBOT
#
tjjfvi#0
`!t6:variance`:

Here's the example with Dog and Animal, explaining co/contra/in variance:

  • Covariance: () => Dog is assignable to () => Animal, because Dog is assignable to Animal; it "preserves the direction of the assignability"
  • Contravariance: (Animal) => void is assignable to (Dog) => void, because something that expects an Animal can also take a Dog; it "reverses the direction of the assignability"
  • Invariance: (Animal) => Animal is not assignable to (Dog) => Dog, because not all returned Animals are Dogs, and (Dog) => Dog is not assignable to (Animal) => Animal, because something expecting a Dog cannot take any other kind of Animal
dreamy current
#

ahhh, I see

#

Hmm, not sure how to fix it then

dense mulch
#

maybe check inside Map to see if it's using a generic from mapStyle as a function parameter type

dreamy current
#
mapStyle?: string | MapStyle | import("./types").ImmutableLike<MapStyle>;
#
export interface ImmutableLike<T> {
  toJS: () => T;
}
dense mulch
#

where is the error exactly?

#

could you make a playground mcve?

dreamy current
#

and finally:

export type StyleSpecification = {
    "version": 8;
    "name"?: string;
    "metadata"?: unknown;
    "center"?: Array<number>;
    "zoom"?: number;
    "bearing"?: number;
    "pitch"?: number;
    "light"?: LightSpecification;
    "sky"?: SkySpecification;
    "terrain"?: TerrainSpecification;
    "sources": {
        [_: string]: SourceSpecification;
    };
    "sprite"?: SpriteSpecification;
    "glyphs"?: string;
    "transition"?: TransitionSpecification;
    "layers": Array<LayerSpecification>;
};
dense mulch
dreamy current
#

Let me try to reproduce

dense mulch
#

that's not a very convincing url though lol

dreamy current
#

haha yeah

#

sorry

dense mulch
#

oh wait

#

check your mapStyle

#

does it have the type version: 8 or version: number

dreamy current
#

my editor says this:

#

that's probably the problem indeed, I'll need to make it a literal 8 probably

#

not sure how I can do that, if I'm importing from json

dense mulch
#

make sure you're hovering over the variable

dreamy current
#

no, sorry, that was actually the object mapStyle, not the attribute

#

this is when I'm hovering over the attribute

dense mulch
#

yeah ok

#

that's weird, usually json gets a const type

dreamy current
#

also I can't seem to reproduce it in the playground, as I can't import a json file there I think

craggy glacierBOT
#
puddingvlaai#0

Preview:ts type StyleSpecification = { version: 8 name?: string // "metadata"?: unknown; // "center"?: Array<number>; // "zoom"?: number; // "bearing"?: number; // "pitch"?: number; // "light"?: LightSpecification; // "sky"?: ...

dense mulch
#

hm, am i hallucinating

dreamy current
#

this just works

#

but yeah I'm not importing from json

dense mulch
dreamy current
#

I think I'm going to put a @ts_ignore on there

#

or, put the json contents in a ts file and assign the type immediately

dense mulch
#

yeah that (the latter) seems to be what most solutions ive found lean towards

#

i swear ive seen json being resolved as const, guess i was hallucinating that memory..?

dreamy current
#

Creating a new file like this also works lol:

import outdoor from '../assets/styles/outdoor.json';
import { StyleSpecification } from 'maplibre-gl';

export const outdoorStyle = outdoor as StyleSpecification;
#

but is ugly, but meh

#

also I've seen some references online to the compiler flag resolveJsonModule but that also doesn't solve the original problem

dense mulch
#

or if you've miswritten something now

dreamy current
#

hmmm

#

I think I can live with that as the library I'm using also does runtime checks on the style

#

if I put the json's in a ts file directly, and assign the type, I do get a lot of errors that the json is not correct haha. Deep within the styles there are some wrong properties

#

so I'm just gonig to ignore it

#

anyway, thank you!

dreamy current
#

yeah it is

dense mulch
#

you're going to get errors at runtime
compiletime checks are there so you don't have to wait for runtime

dreamy current
#

but I'm also too lazy to look why the style is wrong, as I've generated it using an online editor

#

and it works, so

dense mulch
dense mulch
dreamy current
#

true

#

but it works for now

#

if I have the energy I may come back to it

#

hmm ok it may be easier then I thought because there's a migration tool for the deprectated stuff in my style

dense mulch
dreamy current
#

good idea

#

alright, the migration tool just solved all the errors

#

so I'm just going to put the json directly in a .ts file

#

and annotate inline