Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Dynamic import with json file doesn't work typescript

Tags:

typescript

So I write a function like this to get test data for multiple environment:

export class DataHelper {
  public static async getTestData(fileName: string): Promise<any> {
    return await import(`../${fileName}`);
  }
}

this will throw: Error: Cannot find module '../test-data.json'

await DataHelper.getTestData('test-data.json')

but this will work:

await DataHelper.getTestData('TestScript')

also this will work:

await import('../test-data.json')

this is my tsconfig.json

{
  "compilerOptions": {
    "target": "es5",
    "module": "commonjs",
    "declaration": true,
    "sourceMap": true,
    "outDir": "./lib",
    "moduleResolution": "node",
    "baseUrl": ".",
    "esModuleInterop": true,
    "experimentalDecorators": true,
    "emitDecoratorMetadata": true,
    "resolveJsonModule": true
  },
  "include": ["src", "example/**/*"],
  "exclude": ["node_modules", "**/__tests__/*"]
}

Can anyone explain what is happening and what should I do instead?

like image 862
real_kappa_guy Avatar asked Feb 15 '26 13:02

real_kappa_guy


2 Answers

You are not actually able to import json files dynamically in TypeScript without the use of import assertions. TypeScript simply allows you to import files with the json extension via a configuration property which sadly differs from the JavaScript specification which can be very confusing for many people. Here is how the import assertions look like but they are not currently supported on Node.js:

// static import
import data from "./foo.json" assert { type: "json" };

// dynamic import
const { default: data } = await import("./foo.json", { assert: { type: "json" } });

TLDR on that is you must assert because the file extension can't be used to determine the file type for security reasons.

Anyways, the best way to get the JSON in Node.js asynchronously is to read the text via fs then use JSON.parse. At least, until Node.js adds support for import assertions which I would assume not make it for a few years onto stable.

Here's an example:

import { readFile } from "fs/promises";

async function readJsonFile(path) {
  const file = await readFile(path, "utf8");
  return JSON.parse(file);
}

readJsonFile("./package.json").then((data) => {
  console.log(data);
});
like image 146
sno2 Avatar answered Feb 18 '26 05:02

sno2


As mentionned "The assert keyword is deprecated as of V8 v12.3 and is planned to be removed by v12.6."

You should now use "with" instead of "assert" like so :

const jsonModule = await import('./foo.json', {
  with: { type: 'json' }
});
like image 44
Théo Eschlimann Avatar answered Feb 18 '26 05:02

Théo Eschlimann



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!