TypeScript導入で得られる「変えていく勇気」 / The courage to change by TypeScript

2bedb1eb8f841cd3c3ae584600b016e0?s=47 OKUNOKENTARO
September 01, 2018

TypeScript導入で得られる「変えていく勇気」 / The courage to change by TypeScript

2018/9/1、GDG DevFest Tokyo 2018にて発表した資料です。

2bedb1eb8f841cd3c3ae584600b016e0?s=128

OKUNOKENTARO

September 01, 2018
Tweet

Transcript

  1. 5ZQF4DSJQUಋೖͰಘΒΕΔ
 ʮม͍͑ͯ͘༐ؾʯ 4FQ (%(%FW'FTU5PLZP !PLVOPLFOUBSP

  2. ୭ w Ԟ໺ݡଠ࿠!PLVOPLFOUBSP w ΫϨε΢ΣΞ୅දɺ ΤϯδχΞ w "OHVMBS೔ຊϢʔβʔձ
 OHLZPUP

  3. ࣥච

  4. ໨࣍ w ͍·ɺ 5ZQF4DSJQUΛ࠾༻͢Δ͜ͱ͕ࣗવͰ͋Δཧ༝ w ੲͷ5ZQF4DSJQUΛ஌ͬͯΔਓͷΑ ͘ ͋Δޡղ wʮม͍͑ͯ͘༐ؾʯ ͱ͸

  5. ͍·ɺ 5ZQF4DSJQUΛ࠾༻͢Δ͜ͱ͕
 ࣗવͰ͋Δཧ༝

  6. 5ZQF4DSJQU w 5ZQF4DSJQU͸ϓϩάϥϛϯάݴޠ w +BWB4DSJQUͷεʔύʔηο τݴޠ w ੩తܕ෇͚Λಋೖ w ίϯύΠϧ࣌ʹܕݕࠪ

    w ೥ʹˠݱࡏ w .JDSPTPGU͕ओಋͰ։ൃ͢ΔΦʔϓϯιʔε
  7. ίϯύΠϧ͕ඞཁ w 5ZQF4DSJQUϑΝΠϧ͸tscͰίϯύΠϧ͢Δ͜ͱͰ
 +BWB4DSJQUϑΝΠϧͱͯ͠ग़ྗ w +BWB4DSJQU͸ݩʑΠϯλϓϦλͰಈ࡞͢Δݴޠ w ॻ͍͙ͯ͢ʹϒϥ΢βͰಈ࡞ w ͦΕͳͷʹɺ

    ͳͥίϯύΠϧ͕ඞཁͳݴޠͱͯ͠ੜ·Εͨ ʁ
  8. "MU+4ˠ#BCFM w ͪΐͬͱ ͨ͠ྺ࢙ͷ࿩ w ೥$PGGFF4DSJQU w ೥5ZQF4DSJQU  

    w ೥#BCFM wʮKT͡Όͳ͍ଞͷϑΝΠϧʯ Λ+BWB4DSJQUϑΝΠϧʹม׵ w ม׵ޙͷϑΝΠϧ͕ಈ࡞͢Ε͹Α͍ͱ͍͏ߟ͑ํ
  9. Ϟδϡʔϧ w αʔόʔαΠ υ޲͚+BWB4DSJQUͷ࣮ߦ؀ڥ/PEFKT஀ੜ w $PNNPO+4 w +BWB4DSJQUΛϞδϡʔϧ୯ҐͰࡉ͔͘෼͚Δػӡ w &4

    w &4.PEVMFT w NPEVMFJNQPSUFYQPSU·ΘΓ͕ ʮߏจ࢓༷ͷΈʯ ܾ·ͬͨ
  10. XFCQBDL w OQN w /PEF1BDLBHF.BOBHFS w ΋ͱ͸/PEFKT༻ͷϞδϡʔϧґଘؔ܎؅ཧ༻ͷπʔϧ w ݱ୅Ͱ͸ϑϩϯ τΤϯ

    υ։ൃͷσϑΝΫ τ ɾ ελϯμʔ υʹ w όοΫΤϯ υɺ ϑϩϯ τΤϯ υؔ܎ͳ͘OQNͰґଘΛ؅ཧ w ϑϩϯ τΤϯ υͳΒ͹XFCQBDLͱ͍͏όϯ υϥʔ࢖ͬͯόϯ υϧϑΝΠϧΛ࡞੒
  11. ॲཧΛ଍͢ͳΒɺ Α Γ҆શଆʹ w ݱ୅ͷ+BWB4DSJQUͰ͸࣮ߦલʹԿ͔ͱॲཧ͕ͪ͠ w #BCFMͳͲͷ τϥϯεύΠϧ w XFCQBDLͰͷόϯ

    υϧ w Ͳ͏࣮ͤߦલʹԿ͔͠Βॲཧ͢ΔͳΒόάΛݮΒͤΔΑ Γ҆શଆʹ޲͚ͨॲཧ΋ w 5ZQF4DSJQUͷίϯύΠϧ ʢ੩తܕݕࠪʣ  w ϓϩάϥϜͷ࣮ߦલʹݕ஌Ͱ͖ΔΤϥʔ͸͢΂ͯ੩తʹݕ஌͓ͯ͘͠
  12. ੲͷ5ZQF4DSJQUΛ஌ͬͯΔਓͷ
 Α ͘ ͋Δޡղ

  13. ޡղܕఆٛϑΝΠϧͷ؅ཧ͕໘౗ w 5ZQF4DSJQUͰɺ +BWB4DSJQUϥΠ ϒϥ ϦΛ࢖͍͍ͨͱ͖
 ͦͷϥΠ ϒϥ ϦͷܕఆٛϑΝΠϧΛඞཁͱ͢Δ w

    ͦͷܕఆٛϑΝΠϧ .d.ts ͸
 ܕఆٛ؅ཧπʔϧΛ࢖ͬͯผ్Πϯε τʔϧ͠ͳ͍ͱ͍͚ͳ͍ w ੲ͸ͦ͏ͩͬͨ w ࠓ͸ҧ͏
  14. OQNͰ؅ཧͰ͖·͢ w ܕఆٛϑΝΠϧ͕ඞཁͳͷ͸ੲͱಉ͡ w ܕఆٛϑΝΠϧ͕%FpOJUFMZ5ZQFEʹϗεςΟ ϯά͞Ε͍ͯΔͷ΋ੲͱಉ͡ w OQNͰͷ؅ཧ͕Մೳʹͳͬͨ w ͨͱ͑͹$

    npm i -D @types/reactͳͲ w package.jsonͰґଘ͍ͯ͠ΔܕఆٛϑΝΠϧΛ֬ೝͰ͖Δ
  15. ޡղҊ݅ʹ్த͔ΒೖΕΒΕͳ͍ w +BWB4DSJQUͰਐΊ͍ͯΔҊ݅ w ్த͔Β5ZQF4DSJQUʹ੾Γସ͑Δͷ͕ࠔ೉ w ͢΂ͯͷϑΝΠϧʹanyΛॻ͍ͯճ֦ͬͯுࢠΛ.tsʹ͠ͳ͍ͱ͍͚ͳ͍ w ੲ͸ͦ͏ͩͬͨ w

    ࠓ͸ҧ͏
  16. ࠞͥͯӡ༻Ͱ͖·͢ w ίϯύΠ ϥΦϓγϣϯͷ--allowJsΛ༗ޮʹ͢Δ
 ·ͨ͸ɺ tsconfig.jsonͷallowJsΛtrueʹ͢Δ w +BWB4DSJQUଆͷੈք͸͢΂ͯanyͰ͋Δͱ ͯ͠
 ஍ಓʹ5ZQF4DSJQUԽΛਐΊΔ

    w ίϯύΠ ϥઃఆϑΝΠϧtsconfig.jsonͰ͸ॳظ஋͕strict: true w .jsΛ.tsʹϦωʔϜͨ͠Βɺ Ͳ͜Λ௚ͤ͹͍͍͔ίϯύΠ ϥ͕ڭ͑ͯ͘ΕΔ
  17. VOLOPXOܕ w 5ZQF4DSJQUΑ Γunknownܕ͕ఆٛ͞Εͨ w ͍··Ͱ͸ ʮΑ ͘Θ͔Βͳ͍΋ͷʯ ͸anyܕͱ͍ͯͨ͠ w

    ࠓޙɺ ྫ͑͹JSON.parse()ͷ໭Γܕ͸
 anyΑ Γunknownͱ ͯ͠ѻ͏ ͱ҆શ ʢඪ४ͷܕఆٛͰ͸anyͱͳ͍ͬͯΔʣ
  18. BOZͱVOLOPXO any unknown ͋ΒΏΔ஋ˠ5 ͋ΒΏΔ஋͸
 anyʹͳΕΔ ͋ΒΏΔ஋͸
 unknownʹͳΕΔ 5ˠ͋ΒΏΔ஋ any͸


    ͋ΒΏΔ஋ʹͳΕΔ unknown͸
 any, unknownʹ͔͠ͳΕͳ͍
  19. ʮม͍͑ͯ͘༐ؾʯ ͱ͸

  20. ԿΛม͍͑ͯ͘ͷ͔ w ϓϩάϥϜͷιʔείʔ υ w ίʔ υ͸෗Δ w ෗ͬͨ෦෼͸আڈ͢Δ w

    ߴ඼࣭ͳϓϩάϥϜͰ͋ΔͨΊʹɺ 
 ৗʹίʔ υશମͷ઱౓Λߴ͘อͨͳ͚Ε͹ͳΒͳ͍
  21. ͳͥ෗Δͷ͔ w ϓϩάϥϛϯά͸ϏϧͷݐஙͰ͸ͳ͍ w ઃܭਤ௨Γʹ׬੒͠ͳ͍ w ίʔ υ֎ͰͷมԽ w ࢓༷ͷมߋɺ

    νʔϜϝϯόʔͷೖΕସ͑ w ։ൃऀͷεΩϧ޲্ ɾ ཁ݅΁ͷख़஌ w ෗Δͱ͸ɺ ίʔ υΛॻ͍͔ͯΒͷ࣌ؒܦաΛࢦ͢ͷͰ͸ͳ͘
 ίʔ υΛॻ͍ͨ࣌఺͔Βݱ࣌఺·Ͱͷɺ ίʔ υ֎ͰͷมԽͷେ͖͞Ͱ͋Δ
  22. Ϧ ϑΝΫλ Ϧ ϯά w ιʔείʔ υΛม͍͑ͯͨ͘Ίʹ͸Ϧ ϑΝΫλ Ϧ ϯά͕ඞཁ

    w ݱ୅ͷϓϩάϥϛϯάʹ͓͍ͯ͸
 ʮҰ౓ಈ࡞ͨ͠ϓϩάϥϜʹ͸ೋ౓ͱखΛՃ͑ͳ͍ʯ ͳΜͯෆՄೳ w ͦ΋ͦ΋ ʮҰ౓ಈ࡞ͨ͠ʯ ΛͲͷ࣌఺ͷಈ࡞ͱ͢Δͷ͔
 ఆٛͰ͖ͳ͍΄Ͳཁ͕݅ڊେʹͳ͍͍ͬͯͬͯΔ w ͢ͳΘͪৗʹϦ ϑΝΫλ Ϧ ϯά͠ଓ͚ͳ͚Ε͹ͳΒͳ͍ wʮม͍͑ͯ͘༐ؾʯ ͕ඞཁ
  23. ܕݕࠪʹΑΔ҆৺ײ w Ϧ ϑΝΫλ Ϧ ϯάதʹ৽ͨͳόάΛ࣋ͪࠐΜͰ͸ͳΒͳ͍ w ςε τ͕͋Ε͹ม͍͚͑ͯΔ w

    ςε τ͕ͳ͚Ε͹ʜʜ w Ұ౓ʹେ෯ͳมߋΛ͠ͳ͍ͳΒɺ ίϯύΠ ϥΛ৴༻͢Δख΋͋Δ wʮςε τ͸ॻ͍ͯͳ͍͚Ͳɺ ίϯύΠϧ ɾ Τϥʔ͕ग़͍ͯͳ͍ʯ  w ˠ ʮগͳ͘ ͱ΋ɺ ίϯύΠϧ ɾ ΤϥʔͱͳΔΑ ͏ͳϛε͸ؚ·Ε͍ͯͳ͍ ʂ ʯ  w ΋ͪΖΜςε τΛॻ͘ʹӽͨ͜͠ͱ͸ͳ͍
  24. ܕݕ͕ࠪ৴༻ͳΒͳ͍ྫ addToFavorites( entryId: number, userId: number ) { // do

    something } toFormattedString( date: Date, format: string, timeZone: string ): string { // do something }
  25. Ҿ਺ʹ஋ΦϒδΣΫ τΛಋೖ addToFavorites( entryId: EntryId, userId: UserId ) { //

    do something } toFormattedString( date: Date, format: DateFormat, timeZone: TimeZone ): string { // do something }
  26. ஋ΦϒδΣΫ τ export abstract class EntryId extends NumberValue { constructor(protected

    value: number) { super(value); } } export abstract class UserId extends NumberValue { constructor(protected value: number) { super(value); } }
  27. ͜Ε͚ͩ͡Ό଍Γͳ͍ w 5ZQF4DSJQU͸4USVDUVSBM5ZQJOH ʢߏ଄ܕʣ ͱ͍͏ܕࣝผ๏Λ༻͍͍ͯΔ w લทͷྫ w EntryIdܕ΋UserIdܕ΋value: numberϓϩύςΟ

    Λ࣋ͭ w ಉ͡ϓϩύςΟ ͔͍࣋ͬͯ͠ͳ͍ͷͰɺ ޓ׵ੑͷ͋ΔܕͱΈͳ͞Εͯ͠· ͏ w /PNJOBM5ZQJOH ʢެশܕʣ Λ࠾༻͢Δݴޠ w ϓϩύςΟʹؔΘΒͣDMBTT͕ҧ͑͹ผͷܕͱͳΔ
  28. ࠞಉ๷ࢭϓϩύςΟ Λ଍͢ 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); } }
  29. ஋ΦϒδΣΫ τͷ਌Ϋϥε 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; } }
  30. جఈΫϥε 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; } }
  31. ܧঝ͸ڞ௨ԽͰ͸ͳ͍ w DMBTTͷܧঝ FYUFOET Λෳ਺ͷΫϥεؒͷॲཧͷڞ௨Խखஈͱ ͯ͠༻͍ͯ͸ͳΒͳ͍ w εύήςΟͷݪҼɺ ͍͍ͩͨޙչ͢Δ w

    FYUFOET͸ڞ௨ԽͷखஈͰ͸ͳ͘ɺ ந৅తੑ࣭ͷදݱͱ ͯ͠࢖͏
 ͜ͷྫͩͱ wʮจࣈྻܥͷΦϒδΣΫ τʯ ͳͷ͔ wʮ਺஋ܥͷΦϒδΣΫ τʯ ͳͷ͔ w Λදݱ͍ͯ͠Δ
  32. ίϯύΠϧ ɾ ΤϥʔΛຯํʹ͚ͭΖ

  33. ಥવͷ࢓༷มߋ w Locatorܕͱ͍͏஋ΦϒδΣΫ τΛ࢖༻ͯ͠։ൃ͍ͯͨ͠ w औҾઌ͔Β߱ͬͯ͘ Δಥવͷ࢓༷มߋ ʂ  w

    Locatorܕͷ಺෦࣮૷Λमਖ਼͠ͳ͍ͱɺ ͦͷ࢓༷ʹରԠͰ͖ͳ͍
  34. ม͍͑ͯͨ͘ΊͷᖰΓग़͠ w ͓΋ΉΖʹLegacyLocatorܕͱ͍͏ո͍͠ܕ໊ʹมߋ w 5ZQF4DSJQUͱ*%&Λ૊Έ߹ΘͤΕ͹੩తղੳʹΑͬͯվ໊΋Ұॠ w ͋ΒͨΊͯ৽͍͠࢓༷Λ࣮૷ͨ͠LocatorܕΛ࣮૷ w ݹ͍LegacyLocatorܕΛҰՕॴLocatorܕʹมߋ్ͨ͠୺ɺ Ұ੪ʹΤϥʔ

    w ͦͷΤϥʔՕॴΛͻͨ͢Β௵͍ͯ͘͠ w ͜ΕΛᖰΓग़͠ͱݺΜͰ͍Δ
  35. ίϯύΠϧ ɾ ΤϥʔΛຯํʹ͚ͭΖ w ίϯύΠϧ ɾ Τϥʔ͸ѱ͍΋ͷͰ͸ͳ͍ w Ή͠Ζ։ൃऀʹৗʹدΓఴ͏ɺ ৺ڧ͍ຯํͰ͋Δ

    w Τϥʔʹײँ ʂ  w QSFUUJFS ʢίʔ υ ɾ ϑΥʔϚολʣ ͱ5ZQF4DSJQUίϯύΠ ϥʹै͓͚ͬͯ͹޾ͤ
  36. ෆ҆ΛऔΓআ͘ w ίʔ υΛม͍͑ͯ͘ ͜ͱ͸ৗʹෆ҆ͱͷઓ͍ w ෆ҆ΛऔΓআͨ͘ΊʹԿ͕Ͱ͖Δ͔ w ςε τΛॻ͘

    w ܕΛॻ͘ wυΩϡϝϯ τΛॻ͘ ʢܕΞϊςʔγϣϯ͸ྑ࣭ͳ υΩϡϝϯ τͰ͋Δʣ  w 5ZQF4DSJQUΛ࠾༻͢Ε͹ɺ ෆ͕҆औΓআ͚ͯ ʮม͍͑ͯ͘༐ؾʯ ΛಘΒΕΔ
  37. 5IBOLZPV