Leonor
Leonor

Reputation: 377

Import JSON file as const in TypeScript

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?

Upvotes: 20

Views: 6529

Answers (2)

dx_over_dt
dx_over_dt

Reputation: 14318

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?

Upvotes: 13

Mahendra Yadav
Mahendra Yadav

Reputation: 34

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

Upvotes: -6

Related Questions