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
2.7k
Podcastを継続する技術 / refactoradio-240119
okunokentaro
1
150
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.6k
Hasura.io RDBをサクサク作る方法はARやO/RMだけじゃなくなりました/hasura-io
okunokentaro
5
610
コードには型アノテーションよりも要件アノテーションを増やせ!/harajukuts2
okunokentaro
14
6.2k
10年と3ヶ月でWebサービスを作った話 / Piyogrammer Conference 2021
okunokentaro
2
990
Other Decks in Technology
See All in Technology
tenntennはなんでnewmoにnew社したの? - YAPC::Hakodate 2024
tenntenn
PRO
0
180
Product Utilization of Large Language Models Starting Today
ymatsuwitter
3
1.3k
Oracle Database 23ai 新機能#4 Rolling Maintenance
oracle4engineer
PRO
0
120
Oracle Database 23ai 新機能#4 Application Continuity
oracle4engineer
PRO
0
120
Case Study: Concurrent Counting
ennael
PRO
0
100
O'Reilly Superstream: Building a RAG App to Chat with Your Data
pamelafox
0
120
AI時代のアジャイル開発(XP祭り2024版) / Agile Development in the AI Era in XPJUG
takaking22
13
3.6k
YAPC::Hakodateの映像記録を支える技術
godan
4
210
【shownet.conf_】AI技術とUX監視の応用でShowNetの基盤を支えるモニタリングシステム
shownet
PRO
0
360
PREEMPT_RT over the years
ennael
PRO
0
350
【shownet.conf_】ネットワークテストの最適化と利便性の追求
shownet
PRO
0
320
山手線一周のパフォーマンス改善
suzukahr
0
150
Featured
See All Featured
For a Future-Friendly Web
brad_frost
174
9.3k
Build The Right Thing And Hit Your Dates
maggiecrowley
31
2.3k
How to Think Like a Performance Engineer
csswizardry
16
1k
The Invisible Customer
myddelton
119
13k
Why You Should Never Use an ORM
jnunemaker
PRO
53
9k
The Power of CSS Pseudo Elements
geoffreycrofte
71
5.3k
GraphQLの誤解/rethinking-graphql
sonatard
65
9.9k
Automating Front-end Workflow
addyosmani
1365
200k
A designer walks into a library…
pauljervisheath
202
24k
It's Worth the Effort
3n
183
27k
Designing with Data
zakiwarfel
98
5.1k
個人開発の失敗を避けるイケてる考え方 / tips for indie hackers
panda_program
92
16k
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