real_kappa_guy
real_kappa_guy

Reputation: 353

Dynamic import with json file doesn't work 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?

Upvotes: 8

Views: 29042

Answers (3)

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' }
});

Upvotes: 0

sno2
sno2

Reputation: 4183

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);
});

Upvotes: 35

Astaros
Astaros

Reputation: 11

According to this Typescript thread

importAttributes "assert" will be no longer supported due to a regression from stage 3 to stage 2.

They are speaking about replacing it by "why" since months.

Upvotes: 1

Related Questions