Skip to content

import ConstJson from './config.json' as const; #32063

Description

Suggestion

The ability to get const types from a JSON configuration file.

If the json is:

{
  "appLocales": ["FR","BE"]
}

I want to import the JSON and get a {appLocales: "FR" | "BE"} type instead of string

As suggested here, this could rely on ES import attributes (stage 4, ES2025, TypeScript 5.3):

import data from "./data.json" with { type: "json", const: true };

Use Cases

The current approach gives a too broad type string. I understand it makes by default, but having the possibility to import a narrower type would be helpful: it would permit me to avoid maintaining both a runtime locale list + a union type that contains the values that are already in the list, ensuring my type and my runtime values are in sync.

It is possible to type a JSON file explicitly using allowArbitraryExtensions: true and a .d.json.ts file, but this doesn't permit to infer the type from the JSON directly, requires explicit typing and maintenance.

Checklist

My suggestion meets these guidelines:

  • This wouldn't be a breaking change in existing TypeScript/JavaScript code
  • This wouldn't change the runtime behavior of existing JavaScript code
  • This could be implemented without emitting different JS based on the types of the expressions
  • This isn't a runtime feature (e.g. library functionality, non-ECMAScript syntax with JavaScript output, etc.)
  • This feature would agree with the rest of TypeScript's Design Goals.

Links:

This feature has been mentioned:

Search Terms

json const assertion import attributes with allowArbitraryExtensions

Activity

  1. Hawkbat commented on Jul 3, 2019

    @Hawkbat

    This would be extremely useful for adding direct support for JSON schemas to TypeScript. This can technically be accomplished with generators right now, but it would be so much more elegant to be able to use mapped types (for example, https://github.com/wix-incubator/as-typed) to map an imported JSON schema to its corresponding TypeScript type. It isn't currently possible to use this approach with a JSON import since the type property of each schema object will be a string instead of 'boolean' | 'string' | 'number' | ....

  2. Porges commented on Jul 20, 2019

    @Porges
    Member

    FWIW I just tried to do this and used the exact same syntax that the issue title uses, if that's any indication of how intuitive it is 😁

  3. dontsave commented on Sep 30, 2019

    @dontsave

    I just tried the exact above syntax also. Const assertion is a fantastic tool and it would be incredible to have the ability to assert static json files at import

  4. mikeselander commented on Dec 5, 2019

    @mikeselander

    I added a note to #26552 and now realize that I put it in the wrong place, so copying it over here :D

    Reading JSON more literally into string types would be a significant improvement to be able to put configs into JSON.

    As an example, the WordPress Gutenberg project is moving towards a JSON registration schema for multiple reasons. The list of available category options could and should be tightly limited to the available options. However, due to this bug, we could never enforce a proper category list which effectively breaks TS linting of the file for anyone wanting to use TS when creating Gutenberg blocks or plugins.

  5. mscottnelson commented on May 13, 2020

    @mscottnelson

    I've been trying to work on a fix for some of these issues here: https://github.com/pabra/json-literal-typer. If your use-case is relatively straightforward (limited special characters, no escape characters in string literals), then it may satisfy some needs. Would love to have this built-in to the language, but hopefully this will be helpful to some in the interim.

  6. Kingwl commented on May 13, 2020

    @Kingwl
    Contributor

    // CC: Daniel Rosenwasser (@DanielRosenwasser) Ryan Cavanaugh (@RyanCavanaugh)

    How about syntax import const ConstJson from './config' and limited for the json modules.
    I'm happy to work on this if it could be accept.

  7. m-b-davis commented on May 13, 2020

    @m-b-davis

    Wenlu Wang (@Kingwl) I think this syntax could be slightly more confusing than the alternatives. It could look similar to the import name when viewed in a sequence of imports. It would be good to get some a view on what the preferred syntax would be for everyone.

    1 - import const myJson from './myJson.json';
    2 - const import myJson from './myJson.json';
    3 - import myJson from './myJson.json' as const';
    

    Personal view:

    #1 - As mentioned above, not sure it's optimal due to distance from import name
    #2 - Perhaps too similar to const foo = 'abc'. I think this would at first pass look more like a variable assignment than an import
    #3 - This is more similar to the behaviour we have for as const so I would vote for this as the one that fits current design the best.

    Thoughts? Have I missed any alternative syntax options?

  8. m-b-davis commented on May 13, 2020

    @m-b-davis

    Also happy to work on this if it progresses!

  9. TheMrZZ commented on May 17, 2020

    @TheMrZZ

    I'm for option #3. This one looks similar to the current "as const" syntax:

    const x = {...} as const

    It makes it more intuitive. Definitely a killer feature for config-based code if Typescript adopts it.

  10. parzhitsky commented on Aug 27, 2020

    @parzhitsky

    As great as this suggestion is, how should TypeScript interpret the type of property in the original comment?

    {
      "appLocales": [ "FR", "BE" ]
    }
    1. Sealed tuplet: readonly [ "FR", "BE" ]
    2. Tuplet: [ "FR", "BE" ]
    3. Array of custom strings: ("FR" | "BE")[]
    4. Array of arbitrary strings: string[] ← the current one

    I think, there's no way for TypeScript to know the desired level of strictness without developer explicitly specifying it somehow, — and it looks like this will have to be done per each file, rather than once in tsconfig.json

  11. parzhitsky commented on Aug 27, 2020

    @parzhitsky

    I think I'm gonna answer my own question 🙂

    The const keyword in as const is not much about inferring the types literally, as it is about declaring the value as immutable, read-only, sealed. That in turn helps to infer the types more literally, without the worry about being too specific.

    With this in mind, it would be intuitive and expected to set the output of *.json modules to be read-only, forbidding any mutable operation on them. This would make it work just like it currently is working with runtime objects and as const assertion.

  12. ThomasAribart commented on Sep 15, 2020

    @ThomasAribart

    Dmytro Parzhytskyi (@parzhitsky) I think most would agree on the 1st suggestion, as it is coherent with the present as const statement, and as it is the narrowest option (other types can easily be derived from it if needed).

  13. daniellwdb commented on Nov 9, 2020

    @daniellwdb

    This is getting even more valuable after Variadic Tuple Types since we can create more types based on the json values, think of json files used for localization so we can extract interpolation. Any thoughts on implementing this yet?

  14. 89 remaining items

  15. james-pre commented on Jan 18, 2026

    @james-pre

    Hey everyone. If you're like me and have work being blocked by this issue you may be interested in a patch for a stable version of TS. I've gone ahead and created one for v5.9.3: https://gist.github.com/james-pre/0764bf9c64428612454d63799dffacc0. You can use something like patch-package to apply the feature from #63008 to your install of TS.

    Edit:

    FYI there was some weirdness with the patch's metadata (file names specifically) since I created it out-of-tree. The new Gist revision should be correct.

    tsc appears to be working correctly but VS Code's intellisense is very much broken. I'm not sure if this has something to do with the patch or my VS Code configuration.

  16. james-pre commented on Jan 18, 2026

    @james-pre

    Okay I made a small mistake when fixing the patch file to work with patch-package. The updated patch in the Gist is working correctly with tsc and with the ts server. Here is a direct link to the patch file: typescript+5.9.3.patch

  17. jtannas commented on Jan 20, 2026

    @jtannas

    heyo - just popping in with an interim solution that's as brute-force and reliable as possible
    https://www.npmjs.com/package/json2const

    npx json2const --write **/*.json 

    It generates a .ts file for each matched json/jsonc file so you can do a 1-to-1 swap.

    - import data from './data.json';
    + import data from './data.json.ts';

    I needed something that'd work with top-level JSON arrays so the .d.ts solutions weren't working for me.

  18. james-pre commented on Jan 20, 2026

    @james-pre

    Hey Joel Tannas (@jtannas) have you tried out my patch? I'd think it would solve your use case really well.

  19. jtannas commented on Jan 20, 2026

    @jtannas

    Hey Joel Tannas (@jtannas) have you tried out my patch? I'd think it would solve your use case really well.

    Not yet but I'm interested in trying it.

    Unfortunately I saw this issue last week before your patch comments and put together that package. Unlucky timing 🤦

  20. jtannas commented on Feb 7, 2026

    @jtannas

    James Prevett (@james-pre)
    Heyo - I've been happily using the patch and am looking forward to this being available in an official release. A quick bit of feedback though:

    In your PR you state:

    The issue suggests using a const import attribute, however this PR uses a compiler option which is much simpler and should be more maintainable.

    This is definitely a corner case, but I have mostly normal sized JSON files but also some monster files (>>100k lines). TS does not like this :)
    It sees the imported type as {} because the JSON is too large & complex for the compiler to reasonably handle. A const import attribute can be applied selectively so that I'm not clobbering TS with absurd data files.

  21. james-pre commented on Apr 8, 2026

    @james-pre

    Patch for v6.0.2: typescript+6.0.2.patch

  22. james-pre commented on Apr 22, 2026

    @james-pre

    Patch for v6.0.3: typescript+6.0.3.patch

  23. Chinoman10 commented on May 19, 2026

    @Chinoman10

    It's been 7 years since this feature has been requested 😭 sounds like such an obvious thing to add (case in point, I, much like the first people in 2019, also tried adding as const only to realize it wasn't possible, and then found this)...

  24. junipertheleprechaun commented on May 19, 2026

    @junipertheleprechaun

    It's been 7 years since this feature has been requested

    Problem is it's (apparently) not a feature microslop needs, and there's no dollar signs attached so...

  25. rfon6ngy commented on May 27, 2026

    @rfon6ngy

    as long as James Prevett (@james-pre) is doing the lords work ❤️, I can survive
    but I agree, it's a pain to patch each updates

  26. james-pre commented on Jul 4, 2026

    @james-pre

    npm is introducing built-in dependency patching (npm patch) in v12.

    You can patch TS by adding this to your package.json:

    "patchedDependencies": {
    		"[email protected]": "patches/[email protected]"
    }

    ... and download the corresponding patch (into patches), [email protected]. The patch will be applied on the next npm install.

  27. Chinoman10 commented on Jul 5, 2026

    @Chinoman10

    npm is introducing built-in dependency patching (npm patch) in v12.

    You can patch TS by adding this to your package.json:

    "patchedDependencies": {
    "[email protected]": "patches/[email protected]"
    }

    ... and download the corresponding patch (into patches), [email protected]. The patch will be applied on the next npm install.

    Bun has had it for quite a while, and it's much faster than npm as well: https://bun.com/docs/pm/cli/patch
    Thanks for the instructions and the good work James Prevett (@james-pre) 🙏

  28. michaelhazan commented on Oct 8, 2026

    @michaelhazan

    Now that typescript 7 is out with the go compiler this cant patched onto it like before, making it pretty much a possible blocker to upgrading to v7 for projects that became dependent on it.

    Why is this still not a part of typescript?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Awaiting More FeedbackThis means we'd like to hear from more people who would be helped by this featureSuggestionAn idea for TypeScript

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions