You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
import ConstJson from './config.json' as const; #32063
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 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' | ....
Reacted by Mihail Malo, Matt Davis, Aleksi Pekkala, Mariano Pardo, Caleb Boyd, Code Scratcher, Nick Ribal, Florian ERNST, Webber Wang, Zach Wegrzyniak and 49 more
Reacted by Mihail Malo, Matt Davis, Mariano Pardo, Caleb Boyd, Florian ERNST, Webber Wang, Zach Wegrzyniak, Michael Young, Daniel Schultz and Sukka
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 😁
Reacted by Mihail Malo, dave kraftsow, Tavis Rudd, dekryptic, Mariano Pardo, Caleb Boyd, Timo Kämäräinen, Nick Ribal, Matt Davis, Florian ERNST and 61 more
Reacted by Kisaragi, levimiller-qhrtech, Jesper Engberg, Matt Davis, Daniel Dhawan, Marko Kosir, Yair, delphiak, Joshua J., Daniel Tamkin and 2 more
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
Reacted by George Pollard, Benny Neugebauer, Mariano Pardo, Timo Kämäräinen, Nick Ribal, Matt Davis, Florian ERNST, somebody1234, Lucas Forster, Guilherme Correa and 20 more
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.
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.
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.
Reacted by Arthur, Zach Wegrzyniak, Thomas Aribart, Almeida, Jonathan Heindl, Daniel Schultz, levimiller-qhrtech, imspace, Alexander Kondratskiy, Sean Alunni and 2 more
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?
Reacted by Pablo Anaya, George Pollard, Michael Scott-Nelson, Florian ERNST, Nick Ribal, Paul Soporan, btoo, Thomas Aribart, Stepan Mikhailiuk, Alexander Koltun and 16 more
Reacted by Nick Ribal, Florian ERNST, Thomas Aribart, Michael Scott-Nelson, Stepan Mikhailiuk, Almeida, Anne Klapwijk, Daniel Schultz, Justice Almanzar, qb20nh and 4 more
I'm for option #3. This one looks similar to the current "as const" syntax:
constx={...}asconst
It makes it more intuitive. Definitely a killer feature for config-based code if Typescript adopts it.
Reacted by Arnaud Barré, Webber Wang, Brian M Hunt, Josh Kramer, Leo, btoo, Dmytro Parzhytskyi, Thomas Aribart, Stepan Mikhailiuk, Tanner Nielsen and 36 more
Reacted by Nick Ribal, Johannes Loewe, Andrew Kaiser, Matt Davis, Webber Wang, Masaru Itoh, Paul Soporan, Josh Kramer, Leo, Thomas Aribart and 13 more
As great as this suggestion is, how should TypeScript interpret the type of property in the original comment?
{
"appLocales": [ "FR", "BE" ]
}
Sealed tuplet: readonly [ "FR", "BE" ]
Tuplet: [ "FR", "BE" ]
Array of custom strings: ("FR" | "BE")[]
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
Reacted by Sebastian Fredriksson Bernholtz, shqld, Charlie Harding and Andrea Ellison
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.
Reacted by Mike Selander, Mihail Malo, Andrew Kaiser, Leo, Thomas Aribart, Catalín Denís Damián, Yaroslav, Matt Lubner, Michael Scott-Nelson, Norman Fuchs and 23 more
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).
Reacted by Juan Melendez, Loïc Nicolas, Tomáš Hübelbauer, Sebastian Fredriksson Bernholtz, Sean Alunni, James Bromwell and Sámal Rasmussen
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?
Reacted by Jan Buschtöns, Willem Veelenturf and Juan Melendez
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.
Reacted by Cristiano Aguzzi and Sérgio Rebelo
Reacted by Dmytro Parzhytskyi, Jan Amann, South Drifter, LyleBennett, scottrepreneur, Jacob Padgett, btoo and Lorenzo Pieri
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
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.
Reacted by mostpinkest, cett-stephen, Théo LUDWIG, Voltra, Sérgio Rebelo and Mateusz Turcza
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)...
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.
Activity
Hawkbat commentedon Jul 3, 2019
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
typeproperty of each schema object will be astringinstead of'boolean' | 'string' | 'number' | ....Porges commentedon Jul 20, 2019
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 😁
dontsave commentedon Sep 30, 2019
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
mikeselander commentedon Dec 5, 2019
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.
mscottnelson commentedon May 13, 2020
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.
Kingwl commentedon May 13, 2020
// 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.
m-b-davis commentedon May 13, 2020
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.
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?
m-b-davis commentedon May 13, 2020
Also happy to work on this if it progresses!
TheMrZZ commentedon May 17, 2020
I'm for option #3. This one looks similar to the current "as const" syntax:
It makes it more intuitive. Definitely a killer feature for config-based code if Typescript adopts it.
parzhitsky commentedon Aug 27, 2020
As great as this suggestion is, how should TypeScript interpret the type of property in the original comment?
{ "appLocales": [ "FR", "BE" ] }readonly [ "FR", "BE" ][ "FR", "BE" ]("FR" | "BE")[]string[]← the current oneI 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
parzhitsky commentedon Aug 27, 2020
I think I'm gonna answer my own question 🙂
The
constkeyword inas constis 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 constassertion.ThomasAribart commentedon Sep 15, 2020
Dmytro Parzhytskyi (@parzhitsky) I think most would agree on the 1st suggestion, as it is coherent with the present
as conststatement, and as it is the narrowest option (other types can easily be derived from it if needed).daniellwdb commentedon Nov 9, 2020
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?
89 remaining items
james-pre commentedon Jan 18, 2026
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-packageto 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.
tscappears 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.james-pre commentedon Jan 18, 2026
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
jtannas commentedon Jan 20, 2026
heyo - just popping in with an interim solution that's as brute-force and reliable as possible
https://www.npmjs.com/package/json2const
It generates a
.tsfile for each matched json/jsonc file so you can do a 1-to-1 swap.I needed something that'd work with top-level JSON arrays so the
.d.tssolutions weren't working for me.james-pre commentedon Jan 20, 2026
Hey Joel Tannas (@jtannas) have you tried out my patch? I'd think it would solve your use case really well.
jtannas commentedon Jan 20, 2026
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 🤦
jtannas commentedon Feb 7, 2026
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:
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. Aconstimport attribute can be applied selectively so that I'm not clobbering TS with absurd data files.james-pre commentedon Apr 8, 2026
Patch for v6.0.2: typescript+6.0.2.patch
james-pre commentedon Apr 22, 2026
Patch for v6.0.3: typescript+6.0.3.patch
Chinoman10 commentedon May 19, 2026
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 constonly to realize it wasn't possible, and then found this)...junipertheleprechaun commentedon May 19, 2026
Problem is it's (apparently) not a feature microslop needs, and there's no dollar signs attached so...
rfon6ngy commentedon May 27, 2026
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
james-pre commentedon Jul 4, 2026
npm is introducing built-in dependency patching (
npm patch) in v12.You can patch TS by adding this to your package.json:
... and download the corresponding patch (into
patches), typescript@6.0.3.patch. The patch will be applied on the nextnpm install.Chinoman10 commentedon Jul 5, 2026
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) 🙏
Added const JSON imports and tests
michaelhazan commentedon Oct 8, 2026
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?