TypeScript에서 JSON 파일 가져 오기


147

나는이 JSON모양이 다음과 같이 해당 파일을 :

{

  "primaryBright":    "#2DC6FB",
  "primaryMain":      "#05B4F0",
  "primaryDarker":    "#04A1D7",
  "primaryDarkest":   "#048FBE",

  "secondaryBright":  "#4CD2C0",
  "secondaryMain":    "#00BFA5",
  "secondaryDarker":  "#009884",
  "secondaryDarkest": "#007F6E",

  "tertiaryMain":     "#FA555A",
  "tertiaryDarker":   "#F93C42",
  "tertiaryDarkest":  "#F9232A",

  "darkGrey":         "#333333",
  "lightGrey":        "#777777"
}

.tsx파일 로 가져 오려고 합니다. 이를 위해 이것을 유형 정의에 추가했습니다.

declare module "*.json" {
  const value: any;
  export default value;
}

그리고 나는 이것을 이렇게 가져오고 있습니다.

import colors = require('../colors.json')

그리고 파일에서 색상을 primaryMain로 사용합니다 colors.primaryMain. 그러나 오류가 발생합니다.

'typeof "* .json"유형에'primaryMain '특성이 없습니다.


3
모듈 선언과 가져 오기 양식에 동의하지 않습니다.
Aluan Haddad

2
예를 보여 주시겠습니까? 나는 타이프 멍청한 놈입니다.
Sooraj

답변:


93

가져 오기 양식과 모듈 선언은 모듈의 모양, 내보내는 내용에 대해 동의해야합니다.

쓸 때 (호환 가능한 모듈 형식을 대상으로 할 때 TypeScript 2.9 이후 JSON을 가져 오기위한 최적의 방법 은 note 참고 )

declare module "*.json" {
  const value: any;
  export default value;
}

지정자가 끝나는 모든 모듈에 이름이라는.json 단일 내보내기 가 있음을 나타 default 냅니다.

이러한 모듈을 올바르게 소비 할 수있는 몇 가지 방법이 있습니다.

import a from "a.json";
a.primaryMain

import * as a from "a.json";
a.default.primaryMain

import {default as a} from "a.json";
a.primaryMain

import a = require("a.json");
a.default.primaryMain

첫 번째 형태는 최고이며 그것이 활용하는 구문 설탕은 JavaScript가 default수출하는 이유 입니다.

그러나 나는 무엇이 잘못되었는지에 대한 힌트를주기 위해 다른 양식을 언급했습니다. 마지막에 특별한주의를 기울이십시오.require내 보낸 바인딩이 아니라 모듈 자체를 나타내는 객체를 제공합니다 .

그렇다면 왜 오류입니까? 당신이 썼기 때문에

import a = require("a.json");
a.primaryMain

그러나 이름이 지정된 내보내기는 없습니다. primaryMain 의해 선언 된"*.json" .

이 모든 것은 모듈 로더가 default원래 선언에서 제안한대로 내보내기로 JSON을 제공한다고 가정합니다 .

참고 : TypeScript 2.9부터 --resolveJsonModule컴파일러 플래그 를 사용하여 TypeScript가 가져온 .json파일을 분석 하고 와일드 카드 모듈 선언이 필요하지 않은 파일 형식에 대한 정확한 정보를 제공하고 파일의 존재 여부를 확인할 수 있습니다. 특정 대상 모듈 형식에서는 지원되지 않습니다.


1
@Royi는 로더에 따라 다릅니다. 원격 파일의 경우await import('remotepath');
Aluan Haddad

28
아래로 스크롤하여 최신 답변을 유지하십시오.
jbmusso 12

@jbmusso 이후 버전의 TypeScript에서 도입 된 개선 사항에 대한 정보를 추가했지만이 답변이 개념적인 것이기 때문에 구식이라고 생각하지 않습니다. 그러나 추가 개선을 제안합니다.
Aluan Haddad 14:07에

1
어떤 사람들은 답의 첫 줄을 복사 / 붙여 넣기 만하면 근본 원인이 아닌 증상 만 고칠 수 있습니다. @kentor의 답변이 더 자세한 내용을 제공하고 더 완전한 답변을 제공한다고 생각합니다. 오늘은이 문제를 해결할 수있는 올바른 방법이라고 명시 적으로 답변 위에 메모를 옮기는 것이 좋습니다.
jbmusso 2014 년

@ Atombit 그것은 분명히 나를 포함한 많은 사람들에게 효과가있었습니다. 허용 된 답변을 내리기 전에 작동하지 않는 문제를 설명해 주시겠습니까?
Aluan Haddad

269

TypeScript 2.9. +를 사용하면 다음과 같이 typesafety 및 intellisense를 사용하여 JSON 파일을 간단히 가져올 수 있습니다.

import colorsJson from '../colors.json'; // This import style requires "esModuleInterop", see "side notes"
console.log(colorsJson.primaryBright);

( documentation ) compilerOptions섹션에 다음 설정을 추가하십시오 .tsconfig.json

"resolveJsonModule": true,
"esModuleInterop": true,

사이드 노트 :

  • Typescript 2.9.0에는이 JSON 기능에 버그가 있으며 2.9.2로 수정되었습니다.
  • esModuleInterop는 colorsJson의 기본 가져 오기에만 필요합니다. false로 설정 한 상태에서 가져와야합니다.import * as colorsJson from '../colors.json'

17
당신은 반드시 필요하지 않습니다 esModuleInterop,하지만 당신은 할 필요가 import * as foo from './foo.json';-은 esModuleInterop내가 그것을 가능하게 시도 할 때 나를 위해 다른 문제를 야기했다.
mpen

1
당신 말이 맞아요, 나는 그것을 부수적으로 추가해야합니다 :-).
kentor

10
참고 : "node"모듈 확인 전략없이 "resolveJsonModule"옵션을 지정할 수 없으므로에 추가해야 "moduleResolution": "node"합니다 tsconfig.json. *.json가져 오려는 파일이 안에 있어야 한다는 단점도 있습니다 "rootDir". 출처 : blogs.msdn.microsoft.com/typescript/2018/05/31/…
Benny Neugebauer

2
@mpen 맞지만 import * as foo from './foo.json'잘못된 가져 오기 양식입니다. 그것은해야 import foo = require('./foo.json');사용하지 않을 경우esModuleInterop
Aluan 하다드를

1
내가 필요한 부분 만 "resolveJsonModule": true있었고 모든 것이 잘되었습니다
Michael Elliott

10

typescript 버전 2.9 이상을 사용하는 것이 쉽습니다. 따라서 @kentor decribed 로 JSON 파일을 쉽게 가져올 수 있습니다 .

그러나 이전 버전을 사용해야하는 경우 :

더 많은 TypeScript 방식으로 JSON 파일에 액세스 할 수 있습니다. 먼저, 새 typings.d.ts위치가 파일 의 include속성 과 동일한 지 확인하십시오 tsconfig.json.

tsconfig.json파일에 include 속성이없는 경우 그런 다음 폴더 구조는 다음과 같아야합니다.

- app.ts
+ node_modules/
- package.json
- tsconfig.json
- typings.d.ts

그러나 당신이 당신의 include재산 을 가지고 있다면 tsconfig.json:

{
    "compilerOptions": {
    },
    "exclude"        : [
        "node_modules",
        "**/*spec.ts"
    ], "include"        : [
        "src/**/*"
    ]
}

그런 다음 속성에 설명 된대로 디렉토리에 typings.d.ts있어야합니다.srcinclude

+ node_modules/
- package.json
- tsconfig.json
- src/
    - app.ts
    - typings.d.ts

많은 응답에서와 같이 모든 JSON 파일에 대한 전역 선언을 정의 할 수 있습니다.

declare module '*.json' {
    const value: any;
    export default value;
}

그러나 나는 이것의 더 타이핑 된 버전을 선호합니다. 예를 들어, 다음 config.json과 같은 구성 파일이 있다고 가정 해 봅시다 .

{
    "address": "127.0.0.1",
    "port"   : 8080
}

그런 다음 특정 유형을 선언 할 수 있습니다.

declare module 'config.json' {
    export const address: string;
    export const port: number;
}

타이프 스크립트 파일로 쉽게 가져올 수 있습니다.

import * as Config from 'config.json';

export class SomeClass {
    public someMethod: void {
        console.log(Config.address);
        console.log(Config.port);
    }
}

그러나 컴파일 단계에서는 JSON 파일을 dist 폴더에 수동으로 복사해야합니다. package.json구성에 스크립트 속성을 추가하기 만하면됩니다 .

{
    "name"   : "some project",
    "scripts": {
        "build": "rm -rf dist && tsc && cp src/config.json dist/"
    }
}

rm -rf는 리눅스 / 유닉스일까요?
Cody

고맙습니다, typings.d.ts가 제자리에 없었습니다. / src로 이동하자마자 오류 메시지가 사라졌습니다.
Gi1ber7

1
@Cody 실제로는 Linux / Unix에 불과합니다.
맥시 버크만

7

TS 정의 파일 (예 : typings.d.ts`)에서 다음 줄을 추가 할 수 있습니다.

declare module "*.json" {
const value: any;
export default value;
}

그런 다음 typescript (.ts) 파일에 추가하십시오.

import * as data from './colors.json';
const word = (<any>data).name;

2
이것은 매우 나쁜 생각입니다.
Aluan Haddad

3
왜 나쁜지 설명해 주시겠습니까 ??? 나는 타이프 스크립트 전문가가 아닙니다. @AluanHaddad
Mehadi Hassan

5
당신의 타입 주장 any은 두 가지 를 말합니다. 1) 당신은 단순히 정의에 의해 그것의 얼굴에 잘못 선언하거나 가져 왔습니다. 어떤 상황에서도 자신이 선언 한 모듈의 가져 오기에 형식 어설 션을 배치 해서는 안됩니다 . 2) 런타임에 어떻게 든 작동하는 미친 로더가 있더라도 신은 금지하지만 여전히 주어진 모양에 모듈에 액세스하는 것은 혼란스럽고 가장 부서지기 쉬운 방법 일 것입니다. * as x from그리고 x from더욱 OP에있는 것보다 실행 현명한 일치하지 않습니다. 이것을하지 마십시오.
Aluan Haddad

5
당신의 응답을 주셔서 감사합니다. 나는 분명히 이해했다. @AluanHaddad
Mehadi Hassan

2

갈 또 다른 방법

const data: {[key: string]: any} = require('./data.json');

이것은 여전히 ​​json 유형을 정의 할 수 있었고 와일드 카드를 사용할 필요가 없습니다.

예를 들어, 사용자 정의 유형 json입니다.

interface User {
  firstName: string;
  lastName: string;
  birthday: Date;
}
const user: User = require('./user.json');

2
이것은 질문과 관련이 없으며 나쁜 습관입니다.
Aluan Haddad

0

종종 Node.js 애플리케이션에서 .json이 필요합니다. TypeScript 2.9에서는 --resolveJsonModule을 사용하여 .json 파일에서 가져 오기, 유형 추출 및 생성이 가능합니다.

예 #

// tsconfig.json

{
    "compilerOptions": {
        "module": "commonjs",
        "resolveJsonModule": true,
        "esModuleInterop": true
    }
}

// .ts

import settings from "./settings.json";

settings.debug === true;  // OK
settings.dry === 2;  // Error: Operator '===' cannot be applied boolean and number


// settings.json

{
    "repo": "TypeScript",
    "dry": false,
    "debug": false
}
작성자 : https://www.typescriptlang.org/docs/handbook/release-notes/typescript-2-9.html

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.