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導入で得られる「変えていく勇気」 / The courage to cha...
Search
OKUNOKENTARO
September 01, 2018
Technology
22
7.7k
TypeScript導入で得られる「変えていく勇気」 / The courage to change by TypeScript
2018/9/1、GDG DevFest Tokyo 2018にて発表した資料です。
OKUNOKENTARO
September 01, 2018
Tweet
Share
More Decks by OKUNOKENTARO
See All by OKUNOKENTARO
トレタO/X アーキテクチャ移行記 Next.js App Router化への道のり / TORETA TECH UPDATE 1
okunokentaro
5
12k
Podcastを継続する技術 / refactoradio-240119
okunokentaro
1
200
Webアプリケーション設計の第一歩は ディレクトリの整理から / Encraft 1
okunokentaro
34
10k
JSONとJSON Schemaを改めて理解する / tokyo_study
okunokentaro
9
2.4k
それでもどうしてRecoilを使うのか / Harajuku.ts Meetup Recoil
okunokentaro
19
5.6k
TypeScriptは10年でこんなに進化しました / TechFeed Experts Night 11
okunokentaro
6
1.8k
Hasura.io RDBをサクサク作る方法はARやO/RMだけじゃなくなりました/hasura-io
okunokentaro
5
700
コードには型アノテーションよりも要件アノテーションを増やせ!/harajukuts2
okunokentaro
14
6.5k
10年と3ヶ月でWebサービスを作った話 / Piyogrammer Conference 2021
okunokentaro
2
1.1k
Other Decks in Technology
See All in Technology
登壇駆動学習のすすめ — CfPのネタの見つけ方と書くときに意識していること
bicstone
3
120
超初心者からでも大丈夫!オープンソース半導体の楽しみ方〜今こそ!オレオレチップをつくろう〜
keropiyo
0
120
Bill One急成長の舞台裏 開発組織が直面した失敗と教訓
sansantech
PRO
2
390
ランサムウェア対策としてのpnpm導入のススメ
ishikawa_satoru
0
210
顧客の言葉を、そのまま信じない勇気
yamatai1212
1
360
CDKで始めるTypeScript開発のススメ
tsukuboshi
1
510
GitHub Issue Templates + Coding Agentで簡単みんなでIaC/Easy IaC for Everyone with GitHub Issue Templates + Coding Agent
aeonpeople
1
250
Context Engineeringが企業で不可欠になる理由
hirosatogamo
PRO
3
630
コンテナセキュリティの最新事情 ~ 2026年版 ~
kyohmizu
2
610
私たち準委任PdEは2つのプロダクトに挑戦する ~ソフトウェア、開発支援という”二重”のプロダクトエンジニアリングの実践~ / 20260212 Naoki Takahashi
shift_evolve
PRO
1
110
AWS Network Firewall Proxyを触ってみた
nagisa53
1
240
AIエージェントを開発しよう!-AgentCore活用の勘所-
yukiogawa
0
180
Featured
See All Featured
Designing for Timeless Needs
cassininazir
0
130
The Anti-SEO Checklist Checklist. Pubcon Cyber Week
ryanjones
0
69
Building the Perfect Custom Keyboard
takai
2
690
Game over? The fight for quality and originality in the time of robots
wayneb77
1
120
Responsive Adventures: Dirty Tricks From The Dark Corners of Front-End
smashingmag
254
22k
Marketing Yourself as an Engineer | Alaka | Gurzu
gurzu
0
130
Dealing with People You Can't Stand - Big Design 2015
cassininazir
367
27k
How to make the Groovebox
asonas
2
1.9k
Rebuilding a faster, lazier Slack
samanthasiow
85
9.4k
Everyday Curiosity
cassininazir
0
130
Why You Should Never Use an ORM
jnunemaker
PRO
61
9.7k
How to Talk to Developers About Accessibility
jct
2
130
Transcript
5ZQF4DSJQUಋೖͰಘΒΕΔ ʮม͍͑ͯ͘༐ؾʯ 4FQ (%(%FW'FTU5PLZP !PLVOPLFOUBSP
୭ w Ԟݡଠ!PLVOPLFOUBSP w ΫϨεΣΞදɺ ΤϯδχΞ w "OHVMBSຊϢʔβʔձ OHLZPUP
ࣥච
࣍ w ͍·ɺ 5ZQF4DSJQUΛ࠾༻͢Δ͜ͱ͕ࣗવͰ͋Δཧ༝ w ੲͷ5ZQF4DSJQUΛͬͯΔਓͷΑ ͘ ͋Δޡղ wʮม͍͑ͯ͘༐ؾʯ ͱ
͍·ɺ 5ZQF4DSJQUΛ࠾༻͢Δ͜ͱ͕ ࣗવͰ͋Δཧ༝
5ZQF4DSJQU w 5ZQF4DSJQUϓϩάϥϛϯάݴޠ w +BWB4DSJQUͷεʔύʔηο τݴޠ w ੩తܕ͚Λಋೖ w ίϯύΠϧ࣌ʹܕݕࠪ
w ʹˠݱࡏ w .JDSPTPGU͕ओಋͰ։ൃ͢ΔΦʔϓϯιʔε
ίϯύΠϧ͕ඞཁ w 5ZQF4DSJQUϑΝΠϧtscͰίϯύΠϧ͢Δ͜ͱͰ +BWB4DSJQUϑΝΠϧͱͯ͠ग़ྗ w +BWB4DSJQUݩʑΠϯλϓϦλͰಈ࡞͢Δݴޠ w ॻ͍͙ͯ͢ʹϒϥβͰಈ࡞ w ͦΕͳͷʹɺ
ͳͥίϯύΠϧ͕ඞཁͳݴޠͱͯ͠ੜ·Εͨ ʁ
"MU+4ˠ#BCFM w ͪΐͬͱ ͨ͠ྺ࢙ͷ w $PGGFF4DSJQU w 5ZQF4DSJQU
w #BCFM wʮKT͡Όͳ͍ଞͷϑΝΠϧʯ Λ+BWB4DSJQUϑΝΠϧʹม w มޙͷϑΝΠϧ͕ಈ࡞͢ΕΑ͍ͱ͍͏ߟ͑ํ
Ϟδϡʔϧ w αʔόʔαΠ υ͚+BWB4DSJQUͷ࣮ߦڥ/PEFKTੜ w $PNNPO+4 w +BWB4DSJQUΛϞδϡʔϧ୯ҐͰࡉ͔͚͘Δػӡ w &4
w &4.PEVMFT w NPEVMFJNQPSUFYQPSU·ΘΓ͕ ʮߏจ༷ͷΈʯ ܾ·ͬͨ
XFCQBDL w OQN w /PEF1BDLBHF.BOBHFS w ͱ/PEFKT༻ͷϞδϡʔϧґଘؔཧ༻ͷπʔϧ w ݱͰϑϩϯ τΤϯ
υ։ൃͷσϑΝΫ τ ɾ ελϯμʔ υʹ w όοΫΤϯ υɺ ϑϩϯ τΤϯ υؔͳ͘OQNͰґଘΛཧ w ϑϩϯ τΤϯ υͳΒXFCQBDLͱ͍͏όϯ υϥʔͬͯόϯ υϧϑΝΠϧΛ࡞
ॲཧΛ͢ͳΒɺ Α Γ҆શଆʹ w ݱͷ+BWB4DSJQUͰ࣮ߦલʹԿ͔ͱॲཧ͕ͪ͠ w #BCFMͳͲͷ τϥϯεύΠϧ w XFCQBDLͰͷόϯ
υϧ w Ͳ͏࣮ͤߦલʹԿ͔͠Βॲཧ͢ΔͳΒόάΛݮΒͤΔΑ Γ҆શଆʹ͚ͨॲཧ w 5ZQF4DSJQUͷίϯύΠϧ ʢ੩తܕݕࠪʣ w ϓϩάϥϜͷ࣮ߦલʹݕͰ͖ΔΤϥʔͯ͢੩తʹݕ͓ͯ͘͠
ੲͷ5ZQF4DSJQUΛͬͯΔਓͷ Α ͘ ͋Δޡղ
ޡղܕఆٛϑΝΠϧͷཧ͕໘ w 5ZQF4DSJQUͰɺ +BWB4DSJQUϥΠ ϒϥ ϦΛ͍͍ͨͱ͖ ͦͷϥΠ ϒϥ ϦͷܕఆٛϑΝΠϧΛඞཁͱ͢Δ w
ͦͷܕఆٛϑΝΠϧ .d.ts ܕఆٛཧπʔϧΛͬͯผ్Πϯε τʔϧ͠ͳ͍ͱ͍͚ͳ͍ w ੲͦ͏ͩͬͨ w ࠓҧ͏
OQNͰཧͰ͖·͢ w ܕఆٛϑΝΠϧ͕ඞཁͳͷੲͱಉ͡ w ܕఆٛϑΝΠϧ͕%FpOJUFMZ5ZQFEʹϗεςΟ ϯά͞Ε͍ͯΔͷੲͱಉ͡ w OQNͰͷཧ͕Մೳʹͳͬͨ w ͨͱ͑$
npm i -D @types/reactͳͲ w package.jsonͰґଘ͍ͯ͠ΔܕఆٛϑΝΠϧΛ֬ೝͰ͖Δ
ޡղҊ݅ʹ్த͔ΒೖΕΒΕͳ͍ w +BWB4DSJQUͰਐΊ͍ͯΔҊ݅ w ్த͔Β5ZQF4DSJQUʹΓସ͑Δͷ͕ࠔ w ͯ͢ͷϑΝΠϧʹanyΛॻ͍ͯճ֦ͬͯுࢠΛ.tsʹ͠ͳ͍ͱ͍͚ͳ͍ w ੲͦ͏ͩͬͨ w
ࠓҧ͏
ࠞͥͯӡ༻Ͱ͖·͢ w ίϯύΠ ϥΦϓγϣϯͷ--allowJsΛ༗ޮʹ͢Δ ·ͨɺ tsconfig.jsonͷallowJsΛtrueʹ͢Δ w +BWB4DSJQUଆͷੈքͯ͢anyͰ͋Δͱ ͯ͠ ಓʹ5ZQF4DSJQUԽΛਐΊΔ
w ίϯύΠ ϥઃఆϑΝΠϧtsconfig.jsonͰॳظ͕strict: true w .jsΛ.tsʹϦωʔϜͨ͠Βɺ Ͳ͜Λ͍͍͔ͤίϯύΠ ϥ͕ڭ͑ͯ͘ΕΔ
VOLOPXOܕ w 5ZQF4DSJQUΑ Γunknownܕ͕ఆٛ͞Εͨ w ͍··Ͱ ʮΑ ͘Θ͔Βͳ͍ͷʯ anyܕͱ͍ͯͨ͠ w
ࠓޙɺ ྫ͑JSON.parse()ͷΓܕ anyΑ Γunknownͱ ͯ͠ѻ͏ ͱ҆શ ʢඪ४ͷܕఆٛͰanyͱͳ͍ͬͯΔʣ
BOZͱVOLOPXO any unknown ͋ΒΏΔˠ5 ͋ΒΏΔ anyʹͳΕΔ ͋ΒΏΔ unknownʹͳΕΔ 5ˠ͋ΒΏΔ any
͋ΒΏΔʹͳΕΔ unknown any, unknownʹ͔͠ͳΕͳ͍
ʮม͍͑ͯ͘༐ؾʯ ͱ
ԿΛม͍͑ͯ͘ͷ͔ w ϓϩάϥϜͷιʔείʔ υ w ίʔ υΔ w ͬͨ෦আڈ͢Δ w
ߴ࣭ͳϓϩάϥϜͰ͋ΔͨΊʹɺ ৗʹίʔ υશମͷΛߴ͘อͨͳ͚ΕͳΒͳ͍
ͳͥΔͷ͔ w ϓϩάϥϛϯάϏϧͷݐஙͰͳ͍ w ઃܭਤ௨Γʹ͠ͳ͍ w ίʔ υ֎ͰͷมԽ w ༷ͷมߋɺ
νʔϜϝϯόʔͷೖΕସ͑ w ։ൃऀͷεΩϧ্ ɾ ཁ݅ͷख़ w Δͱɺ ίʔ υΛॻ͍͔ͯΒͷ࣌ؒܦաΛࢦ͢ͷͰͳ͘ ίʔ υΛॻ͍͔ͨ࣌Βݱ࣌·Ͱͷɺ ίʔ υ֎ͰͷมԽͷେ͖͞Ͱ͋Δ
Ϧ ϑΝΫλ Ϧ ϯά w ιʔείʔ υΛม͍͑ͯͨ͘ΊʹϦ ϑΝΫλ Ϧ ϯά͕ඞཁ
w ݱͷϓϩάϥϛϯάʹ͓͍ͯ ʮҰಈ࡞ͨ͠ϓϩάϥϜʹೋͱखΛՃ͑ͳ͍ʯ ͳΜͯෆՄೳ w ͦͦ ʮҰಈ࡞ͨ͠ʯ ΛͲͷ࣌ͷಈ࡞ͱ͢Δͷ͔ ఆٛͰ͖ͳ͍΄Ͳཁ͕݅ڊେʹͳ͍͍ͬͯͬͯΔ w ͢ͳΘͪৗʹϦ ϑΝΫλ Ϧ ϯά͠ଓ͚ͳ͚ΕͳΒͳ͍ wʮม͍͑ͯ͘༐ؾʯ ͕ඞཁ
ܕݕࠪʹΑΔ҆৺ײ w Ϧ ϑΝΫλ Ϧ ϯάதʹ৽ͨͳόάΛ࣋ͪࠐΜͰͳΒͳ͍ w ςε τ͕͋Εม͍͚͑ͯΔ w
ςε τ͕ͳ͚Εʜʜ w Ұʹେ෯ͳมߋΛ͠ͳ͍ͳΒɺ ίϯύΠ ϥΛ৴༻͢Δख͋Δ wʮςε τॻ͍ͯͳ͍͚Ͳɺ ίϯύΠϧ ɾ Τϥʔ͕ग़͍ͯͳ͍ʯ w ˠ ʮগͳ͘ ͱɺ ίϯύΠϧ ɾ ΤϥʔͱͳΔΑ ͏ͳϛεؚ·Ε͍ͯͳ͍ ʂ ʯ w ͪΖΜςε τΛॻ͘ʹӽͨ͜͠ͱͳ͍
ܕݕ͕ࠪ৴༻ͳΒͳ͍ྫ addToFavorites( entryId: number, userId: number ) { // do
something } toFormattedString( date: Date, format: string, timeZone: string ): string { // do something }
ҾʹΦϒδΣΫ τΛಋೖ addToFavorites( entryId: EntryId, userId: UserId ) { //
do something } toFormattedString( date: Date, format: DateFormat, timeZone: TimeZone ): string { // do something }
ΦϒδΣΫ τ export abstract class EntryId extends NumberValue { constructor(protected
value: number) { super(value); } } export abstract class UserId extends NumberValue { constructor(protected value: number) { super(value); } }
͜Ε͚ͩ͡ΌΓͳ͍ w 5ZQF4DSJQU4USVDUVSBM5ZQJOH ʢߏܕʣ ͱ͍͏ܕࣝผ๏Λ༻͍͍ͯΔ w લทͷྫ w EntryIdܕUserIdܕvalue: numberϓϩύςΟ
Λ࣋ͭ w ಉ͡ϓϩύςΟ ͔͍࣋ͬͯ͠ͳ͍ͷͰɺ ޓੑͷ͋ΔܕͱΈͳ͞Εͯ͠· ͏ w /PNJOBM5ZQJOH ʢެশܕʣ Λ࠾༻͢Δݴޠ w ϓϩύςΟʹؔΘΒͣDMBTT͕ҧ͑ผͷܕͱͳΔ
ࠞಉࢭϓϩύςΟ Λ͢ type PreventEquation = void; export abstract class EntryId
extends NumberValue { EntryId: PreventEquation; constructor(protected value: number) { super(value); } } export abstract class UserId extends NumberValue { UserId: PreventEquation; constructor(protected value: number) { super(value); } }
ΦϒδΣΫ τͷΫϥε export abstract class NumberValue extends Value<number> { constructor(protected
value: number) { super(value); } lt(other: NumberValue): boolean { return this.value < other.value; } lte(other: NumberValue): boolean { return this.value <= other.value; } }
جఈΫϥε export abstract class Value<T> { constructor(protected value: T) {
// } toString(): string { return this.value.toString(); } valueOf(): T { return this.value; } eq(other: Value<T>): boolean { return this.value === other.value; } }
ܧঝڞ௨ԽͰͳ͍ w DMBTTͷܧঝ FYUFOET ΛෳͷΫϥεؒͷॲཧͷڞ௨Խखஈͱ ͯ͠༻͍ͯͳΒͳ͍ w εύήςΟͷݪҼɺ ͍͍ͩͨޙչ͢Δ w
FYUFOETڞ௨ԽͷखஈͰͳ͘ɺ நతੑ࣭ͷදݱͱ ͯ͠͏ ͜ͷྫͩͱ wʮจࣈྻܥͷΦϒδΣΫ τʯ ͳͷ͔ wʮܥͷΦϒδΣΫ τʯ ͳͷ͔ w Λදݱ͍ͯ͠Δ
ίϯύΠϧ ɾ ΤϥʔΛຯํʹ͚ͭΖ
ಥવͷ༷มߋ w Locatorܕͱ͍͏ΦϒδΣΫ τΛ༻ͯ͠։ൃ͍ͯͨ͠ w औҾઌ͔Β߱ͬͯ͘ Δಥવͷ༷มߋ ʂ w
Locatorܕͷ෦࣮Λमਖ਼͠ͳ͍ͱɺ ͦͷ༷ʹରԠͰ͖ͳ͍
ม͍͑ͯͨ͘ΊͷᖰΓग़͠ w ͓ΉΖʹLegacyLocatorܕͱ͍͏ո͍͠ܕ໊ʹมߋ w 5ZQF4DSJQUͱ*%&ΛΈ߹ΘͤΕ੩తղੳʹΑͬͯվ໊Ұॠ w ͋ΒͨΊͯ৽͍༷͠Λ࣮ͨ͠LocatorܕΛ࣮ w ݹ͍LegacyLocatorܕΛҰՕॴLocatorܕʹมߋ్ͨ͠ɺ Ұ੪ʹΤϥʔ
w ͦͷΤϥʔՕॴΛͻͨ͢Β௵͍ͯ͘͠ w ͜ΕΛᖰΓग़͠ͱݺΜͰ͍Δ
ίϯύΠϧ ɾ ΤϥʔΛຯํʹ͚ͭΖ w ίϯύΠϧ ɾ Τϥʔѱ͍ͷͰͳ͍ w Ή͠Ζ։ൃऀʹৗʹدΓఴ͏ɺ ৺ڧ͍ຯํͰ͋Δ
w Τϥʔʹײँ ʂ w QSFUUJFS ʢίʔ υ ɾ ϑΥʔϚολʣ ͱ5ZQF4DSJQUίϯύΠ ϥʹै͓͚ͬͯͤ
ෆ҆ΛऔΓআ͘ w ίʔ υΛม͍͑ͯ͘ ͜ͱৗʹෆ҆ͱͷઓ͍ w ෆ҆ΛऔΓআͨ͘ΊʹԿ͕Ͱ͖Δ͔ w ςε τΛॻ͘
w ܕΛॻ͘ wυΩϡϝϯ τΛॻ͘ ʢܕΞϊςʔγϣϯྑ࣭ͳ υΩϡϝϯ τͰ͋Δʣ w 5ZQF4DSJQUΛ࠾༻͢Εɺ ෆ͕҆औΓআ͚ͯ ʮม͍͑ͯ͘༐ؾʯ ΛಘΒΕΔ
5IBOLZPV