Let's say I have the following JSON:
[
{ "type": "one", "tile": { "x": 0, "y": 0 }},
{ "type": "two", "tile": null }
]
and I import it into a TypeScript module:
import dataJson from "data.json";
If I write type T = typeof dataJson;
then T
is defined as:
type T = ({
type: string;
tile: {
x: number;
y: number;
};
} | {
type: string;
tile: null;
})[]
However, what I really want is this:
enum Type {
one,
two
}
interface Entry {
type: Type,
tile: {
x: number,
y: number
} | null
}
const data: Entry[] = dataJson;
Unfortunately, TypeScript complains about this:
Types of property 'type' are incompatible. Type 'string' is not assignable to type 'FeatureType'. ts(2322)
I know why this is happening, but I can't seem to find a way around it. Is there a way to somehow coerce the auto-generated typeof dataJson
into Entry
?
CodePudding user response:
You don't like as any
, understood. How about as Entry[]
?
type Entry = (typeof dataJson)[number] & { type: "one" | "two" }
const data = dataJson as Entry[]
// as oppose to
const data: Entry[] = dataJson
// which still gives you error
It seems to me you're not familiar with enum in TS, I also include some side note on the topic (optional reading material).
CodePudding user response:
It seems like, so far, the only way to do this is the following (thanks to @hackape and @pascalpuetz for getting me there):
import dataJson from "data.json";
enum Type {
one = "one",
two = "two"
}
interface Entry {
type: Type,
tile: {
x: number,
y: number
} | null
}
// "as any" seems to be the only way to coerce `type: string` to `type: Type`
const data: Entry[] = dataJson as any;
I'm okay with as any
in this case since JSON is fundamentally much more weakly typed than TypeScript anyway.