Importing JSON Files in TypeScript

TypeScript provides several ways to import JSON files, offering type safety and improved developer experience. This tutorial covers the recommended approaches, from the modern, built-in features of TypeScript 2.9 and later, to older techniques for compatibility.

Modern Approach: resolveJsonModule

Starting with TypeScript 2.9, importing JSON files is significantly simplified. TypeScript can natively handle JSON files as modules, providing type checking and autocompletion. To enable this feature, you need to configure your tsconfig.json file. Add the following to the compilerOptions section:

{
  "compilerOptions": {
    "resolveJsonModule": true,
    "esModuleInterop": true 
  }
}
  • resolveJsonModule: true This flag instructs the TypeScript compiler to treat .json files as modules.
  • esModuleInterop: true This flag enables better interoperability with CommonJS modules and is often recommended when using resolveJsonModule. It ensures that imported JSON files behave as expected in modern JavaScript environments.

With this configuration, you can directly import your JSON file using a simple import statement:

import colors from './colors.json';

console.log(colors.primaryBright); // Access properties directly

TypeScript will infer the type of the imported JSON object, allowing you to access its properties safely and with autocompletion.

Important Considerations:

  • TypeScript Version: Ensure you are using TypeScript version 2.9 or later to utilize resolveJsonModule.
  • Module System: This approach works best with modern module systems (ES Modules). If you are using CommonJS, you may need to adjust your module settings.

Typed JSON Imports (For Enhanced Safety)

While TypeScript infers types from JSON files, you can further improve type safety by explicitly defining the structure of your JSON data. This is particularly useful for complex JSON files where inference might not be sufficient.

  1. Declare a Module: In a .d.ts file (a declaration file), define a module that matches the name of your JSON file.

  2. Define the JSON Structure: Inside the module, export constants or variables that represent the properties of your JSON data, along with their respective types.

Example:

Let’s assume you have a config.json file:

{
  "address": "127.0.0.1",
  "port": 8080
}

Here’s how you could create a config.d.ts file:

declare module 'config.json' {
  export const address: string;
  export const port: number;
}

Now, in your TypeScript code, you can import and use the configuration:

import * as Config from 'config.json';

console.log(Config.address);
console.log(Config.port);

This provides stronger type checking and helps prevent runtime errors.

Older Approaches (For Compatibility)

If you are working with older TypeScript versions or need to maintain compatibility with legacy codebases, you can use declaration files to define the structure of your JSON files.

  1. Global Declaration: Add the following declaration to a .d.ts file:
declare module '*.json' {
  const value: any;
  export default value;
}

This tells TypeScript that any file ending in .json should be treated as a module exporting a single value of type any.

  1. Import the JSON file:
import colors from './colors.json';

console.log(colors.primaryBright);

Note that this approach does not provide strong type checking, as the imported value is of type any. You may need to add additional type assertions or type guards to ensure type safety.

Copying JSON Files during Build (for older setups)
If you’re using older TypeScript versions or a build process that doesn’t automatically copy assets, you may need to explicitly copy your JSON files to the output directory. You can add a script to your package.json to handle this:

{
  "scripts": {
    "build": "rm -rf dist && tsc && cp src/config.json dist/"
  }
}

This script removes the dist directory, compiles your TypeScript code, and then copies the config.json file to the dist directory. Adjust the file paths as needed.

Leave a Reply

Your email address will not be published. Required fields are marked *