James Pond
James Pond

Reputation: 277

Proper way to thoroughly write a JSON object typing

In here: https://hackernoon.com/import-json-into-typescript-8d465beded79, I read it is possible to import JSON objects to my TypeScript project. I did that with the following JSON:

{
  "defaultLanguage": "en",
  "languageMap": {
    "en": "English",
    "pl": "Polish",
    "de": "German"
  }
}

I now want to make sure that any future changes to this file do not break my application so I introduced a following interface to the imported object:

export default interface IConfig {
  defaultLanguage: string;
  languageMap: ILanguage
}

interface ILanguage {
  [language: string]: string
}

I have changed the typings.d.ts file:

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

And imported to my Angular component:

import IConfig from './IConfig';          // Tried to put IConfig 
                                          // as a type in multiple places.
import * as config from './config.json';
(...)
private languageMap = config.languageMap; // in this line my Visual Studio Code 
                                          // underlines languageMap and shows
                                          // the following error:

[ts] Property 'languageMap' does not exist on type 'typeof "*.json"'.

And below:

any

I am wondering if there is a way not to use (<any>config).languageMap but to include my IConfig interface, as suggested in the link above.

Upvotes: 1

Views: 396

Answers (1)

Titian Cernicova-Dragomir
Titian Cernicova-Dragomir

Reputation: 250226

The module *.json module defines a wilds card module that will match any file ending with json and will type the json value as any. You can define a more specific module for config.json.

You can place a config.json.d.ts along side the config.json file describing the json:

//config.json.d.ts
interface IConfig {
    defaultLanguage: string;
    languageMap: ILanguage
}

interface ILanguage {
    [language: string]: string
}
declare const value: IConfig;
export = value;

// usage.ts
import * as config from './config.json';

var languageMap = config.defaultLanguage; // All ok

Or if you use a module system taht does not support export=value you can use this definitions:

//config.json.d.ts
export let defaultLanguage: string;
export let languageMap: ILanguage

interface ILanguage {
    [language: string]: string
}

Upvotes: 2

Related Questions