I am pretty new to TypeScript and have searched quite a while now but could not find a solution specific to my problem.
In my SvelteKit application, I have a json file like that:
{
"some-key": {
"title": "some title",
"content": "some content"
}
}
The file is being imported into a TypeScript file ( page.ts
from SvelteKit routing) and I want to access some-key
dynamically:
import { error } from '@sveltejs/kit';
import type { PageLoad } from './$types';
import data from '../data.json';
export const load: PageLoad = ({ params }) => {
if (data[params.slug]) {
return data[params.slug];
}
throw error(404, 'Not found');
}
Both lines with data[params.slug]
are yelling at me in TypeScript:
Element implicitly has an 'any' type because expression of type 'string' can't be used to index type '{ "some-key": { title: string; content: string; }; }'.
No index signature with a parameter of type 'string' was found on type '{ "some-key": { title: string; content: string; }; }'.
I think TypeScript needs to know about the keys, somehow? Maybe the issue here is easy to fix. But I am stuck and hope someone could help me.
CodePudding user response:
The issue seems to be that the type of the JSON is { "some-key": { title: string; content: string; }; }
but you want it to be { [key: string]: { title: string; content: string; }; }
.
Probably what I would do is use a .ts
file instead of JSON. That way you can also ensure that it is correctly formed and you get nicer typing annotations. Something like this:
interface PageData {
title: string,
content: string,
}
export const data: Record<string, PageData> = {
"some-key": {
title: "Some title",
content: "Some content",
},
}
This should work.
CodePudding user response:
I solved it by re-assigning the JSON object to a variable and type that with an interface:
import { error } from '@sveltejs/kit';
import type { PageLoad } from './$types';
import data from '../data.json';
interface Data {
[slug: string]: {
title: string;
content: string;
};
}
const dataObject: Data = data;
export const load: PageLoad = ({ params }) => {
if (dataObject[params.slug]) {
return dataObject[params.slug];
}
throw error(404, 'Not found');
}
Please comment, if you see a better/simpler way of doing it.