はじめに
TypeScriptでオブジェクトをループするためにはいくつか方法があり、実装している中でいくつか詰まった点があったため記載します。
環境
TypeScript:Version 4.7.2
Node.js:v16.15.0
①for-in文
昔からあるfor-in文を使う方法があります。
const obj = {
foo: "FOO",
bar: "BAR",
baz: "BAZ",
};
for (const key in obj) {
console.log(key, obj[key]);
}
私の環境ではtsconfig.json
を"strict": true
で設定しているため、以下のエラーが出力されます。
return new TSError(diagnosticText, diagnosticCodes, diagnostics);
^
TSError: ⨯ Unable to compile TypeScript:
memo.ts:271:27 - error TS7053: Element implicitly has an 'any' type because expression of type 'string' can't be used to index type '{ foo: string; bar: string; baz: string; }'.
No index signature with a parameter of type 'string' was found on type '{ foo: string; bar: string; baz: string; }'.
271 console.log(key, obj[key]);
~~~~~~~~~~~~
at createTSError (/home/takaya/ProgrammingTypeScript/node_modules/ts-node/src/index.ts:859:12)
at reportTSError (/home/takaya/ProgrammingTypeScript/node_modules/ts-node/src/index.ts:863:19)
at getOutput (/home/takaya/ProgrammingTypeScript/node_modules/ts-node/src/index.ts:1077:36)
at Object.compile (/home/takaya/ProgrammingTypeScript/node_modules/ts-node/src/index.ts:1433:41)
at Module.m._compile (/home/takaya/ProgrammingTypeScript/node_modules/ts-node/src/index.ts:1617:30)
at Module._extensions..js (node:internal/modules/cjs/loader:1159:10)
at Object.require.extensions.<computed> [as .ts] (/home/takaya/ProgrammingTypeScript/node_modules/ts-node/src/index.ts:1621:12)
at Module.load (node:internal/modules/cjs/loader:981:32)
at Function.Module._load (node:internal/modules/cjs/loader:822:12)
at Function.executeUserEntryPoint [as runMain] (node:internal/modules/run_main:77:12) {
diagnosticCodes: [ 7053 ]
}
どうやらobj
にtypestring
のパラメータを持つインデックスシグネチャがないと言われていますね。
そこでインデックスシグネチャを追加して実行してみます。
type Obj = {
[key: string]: string;
};
const obj: Obj = {
foo: "FOO",
bar: "BAR",
baz: "BAZ",
};
for (const key in obj) {
console.log(key as any, obj[key]);
}
実行してみると問題なく実行できました。
foo FOO
bar BAR
baz BAZ
もう1つの方法として、ループ内で型を指定する方法があります。
const obj = {
foo: "FOO",
bar: "BAR",
baz: "BAZ",
};
for (const key in obj) {
console.log(key as any, obj[key as keyof typeof obj]);
}
こちらでも問題なく実行できます。
foo FOO
bar BAR
baz BAZ
②for-of文
Object.entries
を利用してループすることができます。こっちの方がfor-in
文よりもスマートに出来ますね。
const obj = {
foo: "FOO",
bar: "BAR",
baz: "BAZ",
};
for (const [key, value] of Object.entries(obj)) {
console.log(key, value);
}
最後に
他の記事を見ると、for-in
文で実装しているものが多かったのですが、tsconfig.json
を"strict": true
で設定しているとエラーが出力されたため、解決するための記事を書いてみました。