Home > OS >  How do I limit the scope of `resolveJsonModule`?
How do I limit the scope of `resolveJsonModule`?

Time:05-21

I'm working on project that uses Typescript and webpack. I have to import json files, and I have to do it in two ways:

  • I have to import project's package.json as a module. This has already been implemented previously.
  • Have to import some json schemas as resources loadable by url. This is what I'm working on right now.

Using package.json (already implemented)

To import package.json, the tsconfig.json contains:

{
  "compilerOptions": {
    "resolveJsonModule": true,
    "paths": {
      "package.json": ["./package.json"]
    }
  },
}

And webpack config has:

  /**
   * Determine the array of extensions that should be used to resolve modules.
   */
  resolve: {
    extensions: [".js", ".ts", ".tsx", ".json"],
    plugins: [
      new TSConfigPathsPlugin({
        configFile: path.join(__dirname, "../../tsconfig.json"),
        logLevel: "info",
        extensions: [".js", ".jsx", ".ts", ".tsx"],
        mainFields: ["browser", "main"],
        baseUrl: tsConfig.baseUrl,
      }),
    ],
  },

And this is how package.json is used:

import packageJson from "package.json";

//...

const release = `${packageJson.version}-${process.platform}`;

This is completely type-safe: ts checks that my package.json has version field. This is working as intended and I don't want to break it.

Using schema json files (what I'm implementing)

To add support for json schemas, I've added them with filenames matching .schema.json$ and have added this to webpack config:

  module: {
    rules: [
      {
        test: /\.schema.json$/,
        type: "asset/resource",
      },
    ],
  },

And this to a global type declaration file:

declare module "*.schema.json" {
  declare const uri: string;
  export default uri;
}

I thought that by doing that, Typescript would interpret import such a file as a simple string. I've been following this example.

However, when I import the schema file in my project:

import someSchemaUri from "./schemas/some-name.schema.json";

// ...

uri = someSchemaUri;

I still get type error:

Type '{ ... }' is not assignable to type 'string'.

Changing resolveJsonModule

If I set resolveJsonModule option to false, this problem goes away, but importing package.json from the previous section starts giving an error:

Module 'package.json' was resolved to 'secret/path/package.json', but '--resolveJsonModule' is not used.

How do I configure my project so that Typescript would interpret these files as a string, but at the some don't lose type safety when I import package.json from the previous section?

CodePudding user response:

As I know, there's no way to override json types once --resolveJsonModule was set. May you consider to disable that flag and write types for package.json manually? It's not time-consuming since you use only one package.json field.

declare module '*.schema.json' {
    const uri: string;
    export default uri;
}

declare module '*package.json' {
    const content: {
        version: string;
    };
    export default content;
}
  • Related