Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

TypeScript - Import JSON file and assign to variable declared with an interface

I have the following JSON file (test.json):

{"test":[
    {"file": "f1.txt", "nr":3},
    {"file": "f4.txt", "nr":4},
    {"file": "f7.txt", "nr":7}
]}

I defined an interface for this JSON structure in TypeScript:

export interface IJsonFiles {
    test: (FileEntity)[];
}

interface FileEntity{
    file: string;
    nr: number;
}

To make the import statement work in TS I had to create a json.d.ts file with the following content:

declare module "*.json" {
    const value: any;
    export default value;
}

Then I import test.json into my code as follows:

import * as b from '../../assets/test.json';
let files: IJsonFiles;
files = b;

This results in the following error:

TS2322: Type 'typeof import("*.json")' is not assignable to type 'IJsonFiles'.  Property 'test' is missing in type 'typeof import("*.json")'.

Can anybody help? Essentially, what I am trying to achieve is:

I want to import JSON files from the file system (don't want to use require!) and I would like to have the JSON structure defined in TS (no implicit any...).

like image 987
Maecky Avatar asked Jun 19 '18 09:06

Maecky


3 Answers

Typescript 2.9 includes support for well-typed JSON importing out of the box. https://blogs.msdn.microsoft.com/typescript/2018/05/31/announcing-typescript-2-9/#json-imports

Edit. You could also just cast your b variable as IJsonFiles type.

import * as b from '../../assets/test.json';
let files: IJsonFiles = <IJsonFiles> b;
like image 151
tokiyu Avatar answered Oct 23 '22 10:10

tokiyu


This is how I import JSON and add type definitions to it on Node v10.16.0 and TypeScript v3.6.3.

venues.json

[
  {
    "id": "c29e3ee4b23342db8afdab4c826ab478",
    "name": "Example",
    "hostnames": [
      "example.com"
    ],
    "shortcode": "example",
    "lickstatsUrl": "https://theregs.co/example",
    "pin": "1234"
  },
  ...
]

index.ts

import _venues from './venues.json';

interface Venue {
  id: string;
  hostnames: string[];
  shortcode: string;
  lickstatsUrl: string;
  pin: string;
}

const venues = _venues as Venue[];
like image 43
sunknudsen Avatar answered Oct 23 '22 12:10

sunknudsen


You can just declare new object with interface. In your case it will be the next:

import venuesRaw from './venues.json';

interface IVenue {
  id: string;
  hostnames: string[];
  shortcode: string;
  lickstatsUrl: string;
  pin: string;
}

const venues: Venue = venuesRaw;
like image 1
Ruslan Korkin Avatar answered Oct 23 '22 10:10

Ruslan Korkin