質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.35%
import

自身のプラットフォーム・プログラム・データセットに対して、外部ソースを取り込むプロセスをimportと呼びます。

JSON

JSON(JavaScript Object Notation)は軽量なデータ記述言語の1つである。構文はJavaScriptをベースとしていますが、JavaScriptに限定されたものではなく、様々なソフトウェアやプログラミング言語間におけるデータの受け渡しが行えるように設計されています。

TypeScript

TypeScriptは、マイクロソフトによって開発された フリーでオープンソースのプログラミング言語です。 TypeScriptは、JavaScriptの構文の拡張であるので、既存の JavaScriptのコードにわずかな修正を加えれば動作します。

React.js

Reactは、アプリケーションのインターフェースを構築するためのオープンソースJavaScriptライブラリです。

Q&A

解決済

1回答

7807閲覧

TypeScriptでのJSONインポートを行う上で、importしたオブジェクトに制約をかけた型を使用したい

Heles

総合スコア2

import

自身のプラットフォーム・プログラム・データセットに対して、外部ソースを取り込むプロセスをimportと呼びます。

JSON

JSON(JavaScript Object Notation)は軽量なデータ記述言語の1つである。構文はJavaScriptをベースとしていますが、JavaScriptに限定されたものではなく、様々なソフトウェアやプログラミング言語間におけるデータの受け渡しが行えるように設計されています。

TypeScript

TypeScriptは、マイクロソフトによって開発された フリーでオープンソースのプログラミング言語です。 TypeScriptは、JavaScriptの構文の拡張であるので、既存の JavaScriptのコードにわずかな修正を加えれば動作します。

React.js

Reactは、アプリケーションのインターフェースを構築するためのオープンソースJavaScriptライブラリです。

0グッド

0クリップ

投稿2020/10/26 14:39

編集2020/10/26 14:42

概要

reacttypescriptを用いた環境でWeb開発を行っており、JSONファイルをimportしてコード上で加工したうえで出力するようなものを作成しています。
JSONからimportしたオブジェクトについて、扱いが難しいのでお知恵をいただければと思います。

コードと症状

/src/reference/testData.json

json

1[ 2 { 3 "name" : "Alice", 4 "gender" : "2" 5 }, 6 { 7 "name" : "Bob", 8 "gender" : "1" 9 }, 10 { 11 "name" : "Charlie" 12 } 13]

/src/App.tsx

typescript

1import React from 'react'; 2import jsonObj from './reference/testData.json' 3 4type tJSON = { 5 name : string, 6 gender?: "1" | "2" 7} 8 9const people1:tJSON[] = jsonObj; 10 11const people2:tJSON[] = jsonObj.filter((people)=>{ 12 if(! ("gender" in people)) return true; 13 if(people.gender === "1") return true; 14 if(people.gender === "2") return true; 15 return false; 16});

上記コードを入力すると、VSCode上でconst people1で下記エラー

型 '({ name: string; gender: string; } | { name: string; gender?: undefined; })[]' を型 'tJSON[]' に割り当てることはできません。 型 '{ name: string; gender: string; } | { name: string; gender?: undefined; }' を型 'tJSON' に割り当てることはできません。 型 '{ name: string; gender: string; }' を型 'tJSON' に割り当てることはできません。 プロパティ 'gender' の型に互換性がありません。 型 'string' を型 '"2" | "1" | undefined' に割り当てることはできません。

const people2で下記エラーが発生します。

型 '({ name: string; gender: string; } | { name: string; gender?: undefined; })[]' を型 'tJSON[]' に割り当てることはできません。

環境

  • os:windows 10
  • editor: Visual Studio Code 1.50.1
  • reactやnode,babelなどのバージョンは必要があれば調べますが、本日$npx create-react-app test-app --template typescriptで新規構築したフォルダでほかの開発をせずに上記のみで作業しましたので、私のtypescriptの知識不足だと考えています。

希望する解決策

tsconfig.json上で"resolveJsonModule": trueが指定されています。そのため自動で型が推測され、jsonObjgenderの型がstring|undefinedで推測されているため、'1'|'2'|undefinedと競合していると考えています。
しかしアプリ側の都合でこちらの制限はかけたいため、下記の解決策のいずれかを希望します。

  1. jsonに型定義を自前で登録して使用する。
  2. JSONからinportしたオブジェクトを別オブジェクトに移す際にfilterなどで適用することをtypescript側に通知する

1番目についてはTypeScriptでJSONファイルを型付きで読み込む(Qiita)などを参考にしてやってみたのですが、うまく適用されませんでした。
2番目についてはperson2が私の認識ですが、こちらもうまくいっていないです。

以上、よろしくお願いします。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Zuishin

2020/10/26 23:25

型の互換性が filter によって保証されるなら、手っ取り早く any とか unknown を通せば良さそうな気もしますが、もし https://teratail.com/questions/300006 の関係者だったらちゃんと教育してください。他人に通じるよう書かなかったくせに、通じなかったからと逆切れして退会のようなことをしてはいけません。
Heles

2020/10/27 02:26

申し訳ありませんが、該当の質問者とは無関係の者です。 個人で新規にアプリ作成をしています。 filterにより型が補正されているのが問題で、一度オブジェクトをバラして再構築する必要があるということですかね? 今職場ですので確認できません。確認でき次第報告させてもらいます。 アドバイスありがとうございました。
Heles

2020/10/27 13:43

自室に戻ったので検証させていただきました。 ``` typescript const people2:tJSON[] = [] jsonObj.forEach((person)=>{ if((! ("gender" in person)) || person.gender === "1" || person.gender === "2"){ const pushObj:tJSON = {name:person.name}; if(person.gender === "1") pushObj.gender = "1"; if(person.gender === "2") pushObj.gender = "2"; people2.push(pushObj); } }); ``` これで一応意図した動作をすることを確認いたしました。filterが型を固定してしまうからそれを回避する必要があったのですね。 実際のコードはかなり複雑なjsonをinportしようとしている以上、この手が使えるかどうかは別途検証する必要があるのと、パフォーマンス的にもよろしくないとは思いますが、手法の1つとして覚えておくことにします。 ご指摘ありがとうございました。
guest

回答1

0

ベストアンサー

こういうことじゃないかもしれませんが、requireでimportすれば怒られはしないと思います

diff

1- import jsonObj from './reference/testData.json' 2+ const jsonObj:tJSON[] = reuire('./reference/testData.json');

投稿2020/10/27 08:22

Hogeike

総合スコア293

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Heles

2020/10/27 13:37

ご回答ありがとうございます。 requireで読込を指定するとany型扱いで処理されるのですね。 anyですので型チェックは行われず、テキトーな型(string[]等)を左辺に指定しても処理されてしまうのですね。 いままでanyについては避けてきたので、挙動が新鮮です。 これで対応できるかどうか検討いたします、そして同時にimportとrequireの違いなどを詳しく調べてみます。
Heles

2020/10/27 14:16

requireでとりあえず課題が解決できそうですので、今回はHogeikeさんをBAとして質問をクローズしたいと思います。 ありがとうございました
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.35%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問