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.5k
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
10k
Podcastを継続する技術 / refactoradio-240119
okunokentaro
1
160
Webアプリケーション設計の第一歩は ディレクトリの整理から / Encraft 1
okunokentaro
34
9.9k
JSONとJSON Schemaを改めて理解する / tokyo_study
okunokentaro
9
2.2k
それでもどうしてRecoilを使うのか / Harajuku.ts Meetup Recoil
okunokentaro
19
5.4k
TypeScriptは10年でこんなに進化しました / TechFeed Experts Night 11
okunokentaro
6
1.7k
Hasura.io RDBをサクサク作る方法はARやO/RMだけじゃなくなりました/hasura-io
okunokentaro
5
630
コードには型アノテーションよりも要件アノテーションを増やせ!/harajukuts2
okunokentaro
14
6.2k
10年と3ヶ月でWebサービスを作った話 / Piyogrammer Conference 2021
okunokentaro
2
1k
Other Decks in Technology
See All in Technology
OpenShift Virtualizationのネットワーク構成を真剣に考えてみた/OpenShift Virtualization's Network Configuration
tnk4on
0
130
新機能VPCリソースエンドポイント機能検証から得られた考察
duelist2020jp
0
210
サーバレスアプリ開発者向けアップデートをキャッチアップしてきた #AWSreInvent #regrowth_fuk
drumnistnakano
0
190
KubeCon NA 2024 Recap: How to Move from Ingress to Gateway API with Minimal Hassle
ysakotch
0
200
1等無人航空機操縦士一発試験 合格までの道のり ドローンミートアップ@大阪 2024/12/18
excdinc
0
150
マイクロサービスにおける容易なトランザクション管理に向けて
scalar
0
110
Fanstaの1年を大解剖! 一人SREはどこまでできるのか!?
syossan27
2
160
プロダクト開発を加速させるためのQA文化の築き方 / How to build QA culture to accelerate product development
mii3king
1
250
UI State設計とテスト方針
rmakiyama
2
300
宇宙ベンチャーにおける最近の情シス取り組みについて
axelmizu
0
110
Microsoft Azure全冠になってみた ~アレを使い倒した者が試験を制す!?~/Obtained all Microsoft Azure certifications Those who use "that" to the full will win the exam! ?
yuj1osm
1
110
あの日俺達が夢見たサーバレスアーキテクチャ/the-serverless-architecture-we-dreamed-of
tomoki10
0
420
Featured
See All Featured
Designing for humans not robots
tammielis
250
25k
Fight the Zombie Pattern Library - RWD Summit 2016
marcelosomers
232
17k
GraphQLとの向き合い方2022年版
quramy
44
13k
Save Time (by Creating Custom Rails Generators)
garrettdimon
PRO
28
900
Designing on Purpose - Digital PM Summit 2013
jponch
116
7k
Why Our Code Smells
bkeepers
PRO
335
57k
The Art of Delivering Value - GDevCon NA Keynote
reverentgeek
8
1.2k
A Modern Web Designer's Workflow
chriscoyier
693
190k
Docker and Python
trallard
41
3.1k
Rebuilding a faster, lazier Slack
samanthasiow
79
8.7k
A Tale of Four Properties
chriscoyier
157
23k
How To Stay Up To Date on Web Technology
chriscoyier
789
250k
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