Upgrade to PRO for Only $50/Year—Limited-Time Offer! 🔥
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
TypeScriptのクロージャで型エ ラーにハマった話
Search
Yuxki
September 28, 2024
0
21
TypeScriptのクロージャで型エ ラーにハマった話
TypeScriptのクロージャで型エラーにハマった話です。
Yuxki
September 28, 2024
Tweet
Share
More Decks by Yuxki
See All by Yuxki
N+1問題について調べてみた
yuxki
0
18
Conoha VPSでIaCはできる!!!
yuxki
0
180
個人ブログ作ってデプロイしました。
yuxki
0
53
チームでプロダクトを作る機会でタスクの自走に役立った、個人開発の経験や習慣。
yuxki
0
51
Featured
See All Featured
What the history of the web can teach us about the future of AI
inesmontani
PRO
0
380
Mozcon NYC 2025: Stop Losing SEO Traffic
samtorres
0
93
The agentic SEO stack - context over prompts
schlessera
0
560
Docker and Python
trallard
47
3.7k
Creating an realtime collaboration tool: Agile Flush - .NET Oxford
marcduiker
35
2.3k
VelocityConf: Rendering Performance Case Studies
addyosmani
333
24k
How To Stay Up To Date on Web Technology
chriscoyier
791
250k
Become a Pro
speakerdeck
PRO
31
5.7k
Marketing to machines
jonoalderson
1
4.3k
Game over? The fight for quality and originality in the time of robots
wayneb77
1
66
How to Think Like a Performance Engineer
csswizardry
28
2.4k
10 Git Anti Patterns You Should be Aware of
lemiorhan
PRO
659
61k
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独自の挙動ではない)
まとめ • クロージャは内側の関数から外側の関数スコープへのアクセスできるもの。 • 外側の変数を内側の関数で参照する場合、外側で確定させた型は内側の関数 では利用できない。 • そのため、必要であればクロージャの中で型を確定させる必要がある。