[{"data":1,"prerenderedAt":670},["ShallowReactive",2],{"content-/eac-light-data-type-errors":3,"all-pages-for-dir":648,"related-/eac-light-data-type-errors":649,"og-image-/eac-light-data-type-errors":669},{"id":4,"title":5,"body":6,"category":633,"concepts":633,"description":634,"extension":635,"meta":636,"navigation":390,"ogImage":633,"path":637,"project_name":633,"published":638,"publishedAt":639,"seo":640,"source":633,"stem":641,"tags":642,"todo":633,"unpublished":638,"updatedAt":639,"__hash__":647},"pages/2025-12/2025-12-16/eac-light-data-type-errors.md","eac-light-data.ts の TypeScript エラー修正レポート",{"type":7,"value":8,"toc":613},"minimark",[9,13,17,21,25,36,39,42,54,103,106,113,238,249,265,271,274,322,325,328,334,437,440,464,467,471,474,557,561,567,570,587,590,609],[10,11,5],"h1",{"id":12},"eac-light-datats-の-typescript-エラー修正レポート",[14,15,16],"h2",{"id":16},"発生した問題",[18,19,20],"p",{},"VSCodeの問題タブに約1,000件以上のTypeScriptエラーが表示されていた。",[22,23,24],"h3",{"id":24},"エラーメッセージ",[26,27,32],"pre",{"className":28,"code":30,"language":31},[29],"language-text","オブジェクト リテラルは既知のプロパティのみ指定できます。\n\"EBIT_Adj._Margin_Pct\" は型 '{ Sales_Adjusted?: number | null | undefined; ... }'\nに対してここで宣言されたプロパティ 'metrics' から取得されています\n","text",[33,34,30],"code",{"__ignoreMap":35},"",[14,37,38],{"id":38},"原因分析",[22,40,41],{"id":41},"根本原因",[18,43,44,45,48,49,53],{},"生成スクリプト",[33,46,47],{},"generate-eac-light-data.mjs","において、",[50,51,52],"strong",{},"型定義と実際のデータ生成とで異なるプロパティ名","を使用していた。",[55,56,57,73],"table",{},[58,59,60],"thead",{},[61,62,63,67,70],"tr",{},[64,65,66],"th",{},"箇所",[64,68,69],{},"プロパティ名",[64,71,72],{},"備考",[74,75,76,90],"tbody",{},[61,77,78,82,87],{},[79,80,81],"td",{},"型定義 (interface)",[79,83,84],{},[33,85,86],{},"EBIT_Adj__Margin_Pct",[79,88,89],{},"アンダースコア2つ",[61,91,92,95,100],{},[79,93,94],{},"実データ (JSON)",[79,96,97],{},[33,98,99],{},"EBIT_Adj._Margin_Pct",[79,101,102],{},"ドット + アンダースコア",[22,104,105],{"id":105},"変換ロジックの問題",[18,107,108,109,112],{},"スクリプト内の ",[33,110,111],{},"toTsKey()"," 関数:",[26,114,118],{"className":115,"code":116,"language":117,"meta":35,"style":35},"language-javascript shiki shiki-themes vitesse-light vitesse-light","function toTsKey(metricName) {\n  return metricName\n    .replace(/-/g, '_')  // ハイフン → アンダースコア\n    .replace(/%/g, 'Pct')  // % → Pct\n}\n","javascript",[33,119,120,147,157,200,232],{"__ignoreMap":35},[121,122,125,129,133,137,141,144],"span",{"class":123,"line":124},"line",1,[121,126,128],{"class":127},"stQ0i","function",[121,130,132],{"class":131},"senZ8"," toTsKey",[121,134,136],{"class":135},"shFtX","(",[121,138,140],{"class":139},"s4oTP","metricName",[121,142,143],{"class":135},")",[121,145,146],{"class":135}," {\n",[121,148,150,154],{"class":123,"line":149},2,[121,151,153],{"class":152},"sHkkW","  return",[121,155,156],{"class":139}," metricName\n",[121,158,160,163,166,168,172,176,178,181,184,187,191,194,196],{"class":123,"line":159},3,[121,161,162],{"class":135},"    .",[121,164,165],{"class":131},"replace",[121,167,136],{"class":135},[121,169,171],{"class":170},"sMJiu","/",[121,173,175],{"class":174},"sLkVR","-",[121,177,171],{"class":170},[121,179,180],{"class":152},"g",[121,182,183],{"class":135},",",[121,185,186],{"class":170}," '",[121,188,190],{"class":189},"sdGka","_",[121,192,193],{"class":170},"'",[121,195,143],{"class":135},[121,197,199],{"class":198},"sxvE3","  // ハイフン → アンダースコア\n",[121,201,203,205,207,209,211,214,216,218,220,222,225,227,229],{"class":123,"line":202},4,[121,204,162],{"class":135},[121,206,165],{"class":131},[121,208,136],{"class":135},[121,210,171],{"class":170},[121,212,213],{"class":174},"%",[121,215,171],{"class":170},[121,217,180],{"class":152},[121,219,183],{"class":135},[121,221,186],{"class":170},[121,223,224],{"class":189},"Pct",[121,226,193],{"class":170},[121,228,143],{"class":135},[121,230,231],{"class":198},"  // % → Pct\n",[121,233,235],{"class":123,"line":234},5,[121,236,237],{"class":135},"}\n",[18,239,240,241,248],{},"この関数は ",[50,242,243,244,247],{},"ドット ",[33,245,246],{},"."," を変換しない","ため:",[250,251,252,259],"ul",{},[253,254,255,256],"li",{},"入力: ",[33,257,258],{},"EBIT-Adj.-Margin-%",[253,260,261,262,264],{},"出力: ",[33,263,99],{}," (ドットが残る)",[18,266,267,268,270],{},"しかし型定義では手動で ",[33,269,86],{}," と書いていたため、不一致が発生。",[14,272,273],{"id":273},"影響を受けたプロパティ",[55,275,276,289],{},[58,277,278],{},[61,279,280,283,286],{},[64,281,282],{},"SQLiteのメトリクス名",[64,284,285],{},"正しいTSキー",[64,287,288],{},"誤った型定義",[74,290,291,305],{},[61,292,293,297,301],{},[79,294,295],{},[33,296,258],{},[79,298,299],{},[33,300,99],{},[79,302,303],{},[33,304,86],{},[61,306,307,312,317],{},[79,308,309],{},[33,310,311],{},"Net-Income-Adj.-Margin-%",[79,313,314],{},[33,315,316],{},"Net_Income_Adj._Margin_Pct",[79,318,319],{},[33,320,321],{},"Net_Income_Adj__Margin_Pct",[14,323,324],{"id":324},"修正内容",[22,326,327],{"id":327},"修正ファイル",[18,329,330,333],{},[33,331,332],{},"apps/web/scripts/generate-eac-light-data.mjs"," の型定義出力部分:",[26,335,337],{"className":115,"code":336,"language":117,"meta":35,"style":35},"// Before (誤り)\noutput.push(`    EBIT_Adj__Margin_Pct?: number | null`)\noutput.push(`    Net_Income_Adj__Margin_Pct?: number | null`)\n\n// After (修正後)\noutput.push(`    'EBIT_Adj._Margin_Pct'?: number | null`)\noutput.push(`    'Net_Income_Adj._Margin_Pct'?: number | null`)\n",[33,338,339,344,367,386,392,397,417],{"__ignoreMap":35},[121,340,341],{"class":123,"line":124},[121,342,343],{"class":198},"// Before (誤り)\n",[121,345,346,349,351,354,356,359,362,364],{"class":123,"line":149},[121,347,348],{"class":139},"output",[121,350,246],{"class":135},[121,352,353],{"class":131},"push",[121,355,136],{"class":135},[121,357,358],{"class":170},"`",[121,360,361],{"class":189},"    EBIT_Adj__Margin_Pct?: number | null",[121,363,358],{"class":170},[121,365,366],{"class":135},")\n",[121,368,369,371,373,375,377,379,382,384],{"class":123,"line":159},[121,370,348],{"class":139},[121,372,246],{"class":135},[121,374,353],{"class":131},[121,376,136],{"class":135},[121,378,358],{"class":170},[121,380,381],{"class":189},"    Net_Income_Adj__Margin_Pct?: number | null",[121,383,358],{"class":170},[121,385,366],{"class":135},[121,387,388],{"class":123,"line":202},[121,389,391],{"emptyLinePlaceholder":390},true,"\n",[121,393,394],{"class":123,"line":234},[121,395,396],{"class":198},"// After (修正後)\n",[121,398,400,402,404,406,408,410,413,415],{"class":123,"line":399},6,[121,401,348],{"class":139},[121,403,246],{"class":135},[121,405,353],{"class":131},[121,407,136],{"class":135},[121,409,358],{"class":170},[121,411,412],{"class":189},"    'EBIT_Adj._Margin_Pct'?: number | null",[121,414,358],{"class":170},[121,416,366],{"class":135},[121,418,420,422,424,426,428,430,433,435],{"class":123,"line":419},7,[121,421,348],{"class":139},[121,423,246],{"class":135},[121,425,353],{"class":131},[121,427,136],{"class":135},[121,429,358],{"class":170},[121,431,432],{"class":189},"    'Net_Income_Adj._Margin_Pct'?: number | null",[121,434,358],{"class":170},[121,436,366],{"class":135},[22,438,439],{"id":439},"修正後のデータファイル再生成",[26,441,445],{"className":442,"code":443,"language":444,"meta":35,"style":35},"language-bash shiki shiki-themes vitesse-light vitesse-light","cd apps/web\nnode scripts/generate-eac-light-data.mjs\n","bash",[33,446,447,456],{"__ignoreMap":35},[121,448,449,453],{"class":123,"line":124},[121,450,452],{"class":451},"sz8Xr","cd",[121,454,455],{"class":189}," apps/web\n",[121,457,458,461],{"class":123,"line":149},[121,459,460],{"class":131},"node",[121,462,463],{"class":189}," scripts/generate-eac-light-data.mjs\n",[14,465,466],{"id":466},"再発防止策",[22,468,470],{"id":469},"_1-ドット入りプロパティには引用符を使用","1. ドット入りプロパティには引用符を使用",[18,472,473],{},"TypeScriptでドットを含むプロパティ名を定義する場合、引用符で囲む必要がある:",[26,475,479],{"className":476,"code":477,"language":478,"meta":35,"style":35},"language-typescript shiki shiki-themes vitesse-light vitesse-light","// 正しい\nmetrics: {\n  'EBIT_Adj._Margin_Pct'?: number | null\n}\n\n// 誤り（ドットなしなら可）\nmetrics: {\n  EBIT_Adj__Margin_Pct?: number | null\n}\n","typescript",[33,480,481,486,496,517,521,525,530,538,552],{"__ignoreMap":35},[121,482,483],{"class":123,"line":124},[121,484,485],{"class":198},"// 正しい\n",[121,487,488,491,494],{"class":123,"line":149},[121,489,490],{"class":131},"metrics",[121,492,493],{"class":135},":",[121,495,146],{"class":135},[121,497,498,501,503,505,508,511,514],{"class":123,"line":159},[121,499,500],{"class":170},"  '",[121,502,99],{"class":189},[121,504,193],{"class":170},[121,506,507],{"class":127},"?:",[121,509,510],{"class":139}," number",[121,512,513],{"class":127}," |",[121,515,516],{"class":127}," null\n",[121,518,519],{"class":123,"line":202},[121,520,237],{"class":135},[121,522,523],{"class":123,"line":234},[121,524,391],{"emptyLinePlaceholder":390},[121,526,527],{"class":123,"line":399},[121,528,529],{"class":198},"// 誤り（ドットなしなら可）\n",[121,531,532,534,536],{"class":123,"line":419},[121,533,490],{"class":131},[121,535,493],{"class":135},[121,537,146],{"class":135},[121,539,541,544,546,548,550],{"class":123,"line":540},8,[121,542,543],{"class":139},"  EBIT_Adj__Margin_Pct",[121,545,507],{"class":127},[121,547,510],{"class":139},[121,549,513],{"class":127},[121,551,516],{"class":127},[121,553,555],{"class":123,"line":554},9,[121,556,237],{"class":135},[22,558,560],{"id":559},"_2-型定義も自動生成する","2. 型定義も自動生成する",[18,562,563,564,566],{},"型定義とデータ生成で同じ変換ロジックを使用することで、不一致を防ぐ。現在のスクリプトは型定義もデータも同じ ",[33,565,111],{}," 関数の結果を使用するよう修正済み。",[14,568,569],{"id":569},"関連ドキュメント",[250,571,572,580],{},[253,573,574,579],{},[575,576,578],"a",{"href":577},"/vscode-problems-analysis","VSCode問題タブの警告分析レポート"," - 以前の同様の分析",[253,581,582,586],{},[575,583,585],{"href":584},"/actual-consensus-improvement-plan","actual-consensus ページ改善計画"," - eac-light-data.ts の作成経緯",[14,588,589],{"id":589},"教訓",[591,592,593,598,603],"ol",{},[253,594,595],{},[50,596,597],{},"自動生成ファイルの型定義は、生成ロジックと同じ変換を使うべき",[253,599,600],{},[50,601,602],{},"特殊文字（ドット、スラッシュ等）を含むプロパティ名は引用符で囲む",[253,604,605,608],{},[50,606,607],{},"TypeScriptエラーは数が多くても根本原因は1つの場合がある","（今回は2プロパティの修正で1,000件以上解消）",[610,611,612],"style",{},"html pre.shiki code .stQ0i, html code.shiki .stQ0i{--shiki-default:#AB5959;--shiki-dark:#AB5959}html pre.shiki code .senZ8, html code.shiki .senZ8{--shiki-default:#59873A;--shiki-dark:#59873A}html pre.shiki code .shFtX, html code.shiki .shFtX{--shiki-default:#999999;--shiki-dark:#999999}html pre.shiki code .s4oTP, html code.shiki .s4oTP{--shiki-default:#B07D48;--shiki-dark:#B07D48}html pre.shiki code .sHkkW, html code.shiki .sHkkW{--shiki-default:#1E754F;--shiki-dark:#1E754F}html pre.shiki code .sMJiu, html code.shiki .sMJiu{--shiki-default:#B5695977;--shiki-dark:#B5695977}html pre.shiki code .sLkVR, html code.shiki .sLkVR{--shiki-default:#AB5E3F;--shiki-dark:#AB5E3F}html pre.shiki code .sdGka, html code.shiki .sdGka{--shiki-default:#B56959;--shiki-dark:#B56959}html pre.shiki code .sxvE3, html code.shiki .sxvE3{--shiki-default:#A0ADA0;--shiki-dark:#A0ADA0}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .sz8Xr, html code.shiki .sz8Xr{--shiki-default:#998418;--shiki-dark:#998418}",{"title":35,"searchDepth":149,"depth":149,"links":614},[615,618,622,623,627,631,632],{"id":16,"depth":149,"text":16,"children":616},[617],{"id":24,"depth":159,"text":24},{"id":38,"depth":149,"text":38,"children":619},[620,621],{"id":41,"depth":159,"text":41},{"id":105,"depth":159,"text":105},{"id":273,"depth":149,"text":273},{"id":324,"depth":149,"text":324,"children":624},[625,626],{"id":327,"depth":159,"text":327},{"id":439,"depth":159,"text":439},{"id":466,"depth":149,"text":466,"children":628},[629,630],{"id":469,"depth":159,"text":470},{"id":559,"depth":159,"text":560},{"id":569,"depth":149,"text":569},{"id":589,"depth":149,"text":589},null,"型定義とデータのプロパティ名の不一致による TypeScript エラーの原因と修正方法","md",{},"/eac-light-data-type-errors",false,"2025-12-16T00:00:00.000Z",{"title":5,"description":634},"2025-12/2025-12-16/eac-light-data-type-errors",[478,643,644,645,646],"type-error","eac-light-data","financial-quiz","bug-fix","dDdpHRXpje6Y_IPnlOLqzQ3s2pD2HCUvReByY8IVhJQ",[],[650,654,658,662,665],{"title":651,"path":652,"publishedAt":653},"月次統計カードにNEWバッジを実装 - データ鮮度で自動点灯・自動消灯させる","/memory-makers-new-badge","2026-07-13T00:00:00.000Z",{"title":655,"path":656,"publishedAt":657},"oshieru-sansu PR #58 マージ後レビューと内角の丸めバグ修正","/oshieru-sansu-pr58-postmerge-review","2026-06-13T00:00:00.000Z",{"title":659,"path":660,"publishedAt":661},"Number.isFinite と isFinite の違い ― JavaScript で「有限の数か」を判定する正しい書き方","/number-isfinite-explained","2026-06-09T00:00:00.000Z",{"title":663,"path":664,"publishedAt":661},"厳密等価演算子（===）と等価演算子（==）の違い ― JavaScript で == を使わない方がいい理由","/strict-equality-vs-loose-equality",{"title":666,"path":667,"publishedAt":668},"旅行ページの『参加者』をSingle Source of Truthへ寄せたリファクタ","/trip-family-members-ssot-refactor","2026-05-29T00:00:00.000Z","https://log.eurekapu.com/og/blog/eac-light-data-type-errors.png?v=2025-12-16T00%3A00%3A00.000Z&title=eac-light-data.ts%20%E3%81%AE%20TypeScript%20%E3%82%A8%E3%83%A9%E3%83%BC%E4%BF%AE%E6%AD%A3%E3%83%AC%E3%83%9D%E3%83%BC%E3%83%88&author=Kei%20Komatsu&sig=4cf21d77dd798b40",1785654679481]