Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
TypeScriptのクロージャで型エ ラーにハマった話
Search
Yuxki
September 28, 2024
0
18
TypeScriptのクロージャで型エ ラーにハマった話
TypeScriptのクロージャで型エラーにハマった話です。
Yuxki
September 28, 2024
Tweet
Share
More Decks by Yuxki
See All by Yuxki
N+1問題について調べてみた
yuxki
0
17
Conoha VPSでIaCはできる!!!
yuxki
0
110
個人ブログ作ってデプロイしました。
yuxki
0
49
チームでプロダクトを作る機会でタスクの自走に役立った、個人開発の経験や習慣。
yuxki
0
49
Featured
See All Featured
ReactJS: Keep Simple. Everything can be a component!
pedronauck
667
120k
Building Applications with DynamoDB
mza
95
6.5k
Facilitating Awesome Meetings
lara
54
6.4k
jQuery: Nuts, Bolts and Bling
dougneiner
63
7.8k
Product Roadmaps are Hard
iamctodd
PRO
54
11k
Typedesign – Prime Four
hannesfritz
42
2.7k
Raft: Consensus for Rubyists
vanstee
140
7k
Bootstrapping a Software Product
garrettdimon
PRO
307
110k
GitHub's CSS Performance
jonrohan
1031
460k
Designing for Performance
lara
610
69k
Designing for humans not robots
tammielis
253
25k
The Cult of Friendly URLs
andyhume
79
6.5k
Transcript
TypeScriptのクロージャで型エ ラーにハマった話 Yukihiro Uejo
自己紹介 • 自己紹介 ◦ エンジニア職への就職(アプリのバックエンド)を目指して、日々勉強中です。 経験者と初心者の中間くらいだと思ってます。(実務2年 →個人開発3年) ▪ 実務2年では、主にJavaとSQLで管理会計のWEBアプリを開発 ▪
個人開発では、主にセキュリティと VPSでオンプレっぽくインフラを勉強して いました。 ◦ Pythonでバックエンドの開発をやってます。 ▪ 最近はNext.jsとTypeScriptでフロントの開発もしています。 2
クロージャとは “クロージャは、組み合わされた(囲まれた)関数と、その周囲の状態(レキシ カル環境)への参照の組み合わせです。言い換えれば、クロージャは内側の関数 から外側の関数スコープへのアクセスを提供します。JavaScript では、関数 が作成されるたびにクロージャが作成されます。” クロージャ https://developer.mozilla.org/ja/docs/Web/JavaScript/Closure s mdn
web docsから引用
つまり • これはクロージャではなく const foo = () => { console.log(“Hello”)
} • これはクロージャ let bar = “Hello” const foo = () => { console.log(bar) }
Array.prototype.map()でも同じことが言える • これはクロージャではなく [1, 2, 3].map((value)=> {return value + 1})
• これはクロージャ let bar = 1 [1, 2, 3].map((value)=> {return value + bar})
ところで
Reactでは以下のような処理がよくある • Web APIでデータを取ってきて、データが取れてきている場合、取ってきた データを使ってmap()の中でReact.Nodeに変換する処理。 • TypeScirptになれていない自分は、↑のmap()の関数内で起こる型エラー にハマってしまった。 • retunする前に、データがundefinedでないことをチェックしているのに、
なぜ型エラーが起きる?
サンプルコード
// 2分の1の確率でundefinedが入る let foo: undefined | string = ["ABC", undefined][Math.floor(Math.random()
* 2)] // ここではエラーが発生する foo.substring(1) if (foo !== undefined) { // ここではエラーが発生しない foo.substring(1) } if (foo !== undefined) { [1, 2, 3].map((value) => { // ここではエラーが発生する foo.substring(value) }) }
結果からいうと • クロージャの中で型のチェックをする必要があった。
エラーが生じた理由 • map()だとしっくりこなかったが、以下のような変数の関数の代入だと理由がはっきりわか る。 let foo: string | undefined =
1 const bar = () => { foo.substring(1) } • barが実際に呼ばれるタイミングでは fooがundefinedになっている可能性は十分に考えら れるため、TypeScriptはfooの型をstringに確定することができない。 (というか多分TypeScript独自の挙動ではない)
まとめ • クロージャは内側の関数から外側の関数スコープへのアクセスできるもの。 • 外側の変数を内側の関数で参照する場合、外側で確定させた型は内側の関数 では利用できない。 • そのため、必要であればクロージャの中で型を確定させる必要がある。