Import JSON file as const in TypeScript
Asked Answered
B

2

19

I would like to create a union type from a property of the elements of an array. If the array were inline, that would be pretty straightforward using a constant assertion.

const arr = [{ "name": "One" }, { "name": "Two" }] as const;

type name = typeof arr[number]["name"];
// name = "One" | "Two"

Note that without as const the type name becomes equal to string, which is not the intent.

The problem I'm facing is that the array is defined in a separate JSON file. I set "resolveJsonModule": true in the TypeScript options so I can import the JSON file in my module. But then the compiler widens the type of all properties in the array as there is no as const on the definition.

import * as arr from "./array.json";

type name = typeof arr[number]["name"];
// name = string (!)

Is there a way I can import a JSON file without type widening?

Benedictus answered 18/2, 2020 at 12:42 Comment(1)
To get the name attribute of the first element, you should be using arr[<idx>].nameTopmost
H
12

I needed an answer to this too, and then realized, "Hey, that wouldn't be a hard npm package to write."

I don't believe there is a pure TS way to do this. The package I created is called ts-json-as-const.

npm install -D ts-json-as-const
npx ts-json-as-const ./path/to/file.json ./path/to/second/file.json
Example JSON file (example.json)
{
  "foo": {
    "bar": false,
    "baz": true,
    "i-can": "hascheezburger"
  },
  "array": [ 1, 2, 3, { "foo": 1, "bar": [ 4, 5 ] }, 6 ]
}
Output example.json.d.ts
interface Example {
  foo: {
    bar: false;
    baz: true;
    'i-can': 'hascheezburger';
  },
  array: [
    1,
    2,
    3,
    {
      foo: 1;
      bar: [
        4,
        5
      ]
    },
    6
  ]
}

declare const Example: Example;

export = Example;

I'll admit, the array spacing isn't great, but who looks at .d.ts files for their json files anyway?

Henryk answered 4/9, 2021 at 23:25 Comment(2)
Thank you for this, though it is annoying that it is necessary! Why wouldn't TS import it as const by default :(Herwig
This answer is misleading today. Typescript supports JSON imports with the "resolveJsonModule" config.Inconsistency
P
-6

https://hackernoon.com/import-json-into-typescript-8d465beded79

example.json:

{
    "name": "testing"
}

javascript:

// ES6/ES2015
// app.js

import * as data from './example.json';

const word = data.name;

console.log(word); // output 'testing'

or In Typescript, however, the same code will throw error:

Cannot find module 'example.json'

[UPDATE] Solution: Typescript 2.9 supports JSON import!

{
  "compilerOptions": {
    "resolveJsonModule": true,
    "esModuleInterop": true  
  }
}
Protoplasm answered 15/7, 2021 at 5:54 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.