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

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

新規登録して質問してみよう
ただいま回答率
85.37%
型推論

型推論とは、コンパイラが型を自動で判断する機能を指します。メソッド内のローカル変数の宣言時に型宣言の代わりに指定することで、コードの記述量を減らすことが可能。変数や関数シグネチャに型を宣言せずとも、早期にエラーをチェックできるというメリットもあります。

オブジェクト

オブジェクト指向において、データとメソッドの集合をオブジェクト(Object)と呼びます。

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

TypeScript

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

配列

配列は、各データの要素(値または変数)が連続的に並べられたデータ構造です。各配列は添え字(INDEX)で識別されています。

Q&A

2回答

464閲覧

TSの型エラーが解消できない

shunta80

総合スコア96

型推論

型推論とは、コンパイラが型を自動で判断する機能を指します。メソッド内のローカル変数の宣言時に型宣言の代わりに指定することで、コードの記述量を減らすことが可能。変数や関数シグネチャに型を宣言せずとも、早期にエラーをチェックできるというメリットもあります。

オブジェクト

オブジェクト指向において、データとメソッドの集合をオブジェクト(Object)と呼びます。

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

TypeScript

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

配列

配列は、各データの要素(値または変数)が連続的に並べられたデータ構造です。各配列は添え字(INDEX)で識別されています。

0グッド

0クリップ

投稿2023/12/10 06:42

実現したいこと

「オブジェクトは 'undefined' である可能性があります。ts(2532)」のエラーが解決できない

前提

配列のデータをカテゴリーごとに分割して新しいオブジェクトを生成する

処理自体は完成したがTSのエラーが解消できない

発生している問題・エラーメッセージ

イメージ説明

該当のソースコード

type BrandData = { brand: string color: string amount: number } type TransformedData = { [key: string]: { [key: string]: number[] } } const data: BrandData[] = [ { brand: 'aaa', color: 'red', amount: 1000, }, { brand: 'aaa', color: 'red', amount: 2000, }, { brand: 'bbb', color: 'blue', amount: 4000, }, ] const transformedData = data.reduce((acc, item) => { const { brand, color, amount } = item if (!acc[brand]) { acc[brand] = {} } if (!acc[brand][color]) { acc[brand][color] = [] } if (!acc[brand][color]?.includes(amount)) { acc[brand][color].push(amount) } return acc }, {} as TransformedData)

試したこと

1.anyの型を使用する
2.非nullアサーションを使用する
if (!acc[brand]![color]) {}

この2つの方法では解消できましたが、lintのエラーに引っかかってしまうため別の解消方法が必要です

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

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

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

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

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

hoshi-takanori

2023/12/10 07:27

該当のソースコード、特にエラーは出ませんけど…。TypeScript のバージョンはいくつですか?
shunta80

2023/12/10 14:14

変数化してエラー解消する具体的な方法わかりましたら教えて頂きたいです🙇‍♂️
guest

回答2

0

トランスパイラはデータをディクショナリに入れたかどうかまでは追ってくれないので、その前に挿入していたとしても、acc[brand]がundefinedになる可能性があると判定され、undefined[color] というアクセスはエラーになるよ、と言われていると思います。なので、トランスパイラにそれはない、とわかるように記述したほうがいいです。

多分こんな感じで、変数に入れるようにしたら大丈夫かと。

TypeScript

1const transformedData = data.reduce((acc, item) => { 2 const { brand, color, amount } = item; 3 4 let colorsOfBrand = acc[brand]; 5 if(!colorsOfBrand){ 6 acc[brand] = colorsOfBrand = {} 7 } 8 // この時点でcolorsOfBrand はundefinedでないと判定できる(同時にacc[brand] も絶対何かが入っている) 9 10 let amountOfColor = colorsOfBrand[color]; 11 if(amountOfColor){ 12 colorsOfBrand[color] = amountOfColor = []; 13 } 14 // この時点でamountOfColor はundefinedでないと判定できる(同時にacc[brand][color] も絶対何かが入っている) 15 16 if(amountOfColor.includes(amount)){ 17 amountOfColor.push(amount); 18 } 19 return acc; 20}, {} as TransformedData); 21

投稿2023/12/10 15:12

Shunly

総合スコア152

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

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

0

ディクショナリではなくRecordを利用する方法はいかがですか?
文字列がキーとなるディクショナリ、という定義だけでは存在しないキーの可能性が潰せないためundefinedになってしまいます。

typescript

1// brandとcolorを文字列ではなく型にする 2type Brand = 'aaa' | 'bbb'; 3type Color = 'red' | 'blue'; 4 5type BrandData = { 6 brand: Brand 7 color: Color 8 amount: number 9} 10 11// Recordで定義する 12type TransformedData = Record<Brand, Record<Color, number[]>> 13 14const data: BrandData[] = [ 15 { 16 brand: 'aaa', 17 color: 'red', 18 amount: 1000, 19 }, 20 { 21 brand: 'aaa', 22 color: 'red', 23 amount: 2000, 24 }, 25 { 26 brand: 'bbb', 27 color: 'blue', 28 amount: 4000, 29 }, 30] 31 32// reduceにジェネリクスで型を指定すればasは不要になる 33const transformedData = data.reduce<TransformedData>((acc, item) => { 34 const { brand, color, amount } = item 35 acc[brand][color].push(amount) 36 return acc 37}, { 'aaa': { 'red': [], 'blue': [] }, 'bbb': { 'red': [], 'blue': [] } }) // 初期値を型通りに設定してreduce内のif文を消す

投稿2024/01/09 05:26

rokumura7

総合スコア2

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

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

ただいまの回答率
85.37%

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

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

質問する

関連した質問