プロダクト開発とTypeScript

 プロダクト開発とTypeScript

TypeScriptによるプロダクト開発の知見

Transcript

  1. Product development with TypeScript

  2. Name !CSO 5BLFUPTIJ"POP੨໺݈ར  Occupation 'SPOUFOE%FWFMPQFS1SPEVDU0XOFS Company $ZCFSBHFOU"EUFDI4UVEJP"*.FTTFOHFS OSS $POUSJCVUPSPG7

    About IUUQJOGPCODI
  3. 1SPEVDUEFWFMPQFEFGGFDUJWFMZ 5ZQF4DSJQUಋೖͯ͠ϓϩμΫτ։ൃͷੜ࢈ੑ͸্͕Γ·͔ͨ͠ʁ ಋೖ͚ͨͩ͠Ͱ͸ͳ͔ͳ͔೉͍͔͠΋͠Ε·ͤΜɻ ࠓ೔ͷτʔΫ͕ ੜ࢈ੑΛͰ͖Δ্͚ͩ͛ΔͨΊͷΨΠυͱͳΔ͜ͱΛئ͍·͢ɻ

  4. *NQPSUBOUUIJOHTBCPVU5ZQF4DSJQU 5ZQF4DSJQUͷॏཁͳ఺Ͱ͢ KBWBTDSJQUͰ͸ͳ͍͕KBWBTDSJQUͰ΋͋Δ ܕ͸࣮ߦ࣌ʹ͸ফ͑Δ

  5. ػೳ

  6. #FGPSFBMM લఏͱͯ͠UTDPOpHKTPOͰҎԼͷػೳ͸ඞͣ0/ʹ͠·͠ΐ͏ OP*NQMJDJU"OZ TUSJDU

  7. *NQPSUBOUUIJOHTBCPVU5ZQF4DSJQU KBWBTDSJQUͰ͸ͳ͍͕KBWBTDSJQUͰ΋͋Δ 5ZQF4DSJQU͸KBWBTDSJQUͷ4VQFS4FUΛᨳ͍ͬͯ·͢ ͦͷͨΊ࢓༷తʹ͸+BWBTDSJQUΛ౿ऻ͍ͯ͠·͕͢ ͋͘·Ͱผͷݴޠͱଊ͑ͨ΄͏͕ྑ͍Ͱ͢ ͦͷ্Ͱ͍͔ͭ͘ॏཁͳ఺ʹ͍͓ͭͯ࿩͠·͢

  8. FOVN FOVN͸5ZQF4DSJQUͷಠࣗػೳͰ͢ KBWBTDSJQUʹ͸ແ͍ͱ͍͏ҙຯࠓޙ΋ಉ ͡ҙຯͰ࢖͍·͢

  9. enum Card { SPADE, HEART, DIAMOND, CLUB } // ࿈൪

    assert.equal(Card.SPADE, 0); assert.equal(Card.DIAMOND, 2); // ٯҾ͖ assert.equal(Card[Card.DIAMOND], 'DIAMOND');
  10. enum Event { CLICK = 'CLICK', MOUSEOVER = 'MOUSEOVER'; }

  11. FOVN FOVN͸͜ͷΑ͏ʹ஋Λ·ͱΊΔͷʹར༻͠·͕͢ FOVNࣗ਎͕ܕΛߏ੒͠ɺܕνΣοΫʹར༻Ͱ͖·͢ ͨͩ͠஫ҙ఺͕͋Γ·͢

  12. enum Card { SPADE, HEART, DIAMOND, CLUB } const fn

    = (card: Card) => { return card; } fn(Card.SPADE); // OK fn(0); // OK fn(10); // OK
  13. FOVN FOVNΛͦͷ··ར༻͢Δͱɺ୯७ͳOVNCFSܕͱͳΓ਺஋ͷൣғΛνΣο Ϋͯ͘͠Ε·ͤΜ ͦͷͨΊෆਖ਼ͳ஋Λ౉͢͜ͱ΋ՄೳʹͳΓ·͢

  14. enum EventType { CLICK = 'CLICK', MOUSEOVER = 'MOUSEOVER'; }

    const fn2 = (event: EventType) => {return event;} fn2(EventType.CLICK); fn2(EventType.MOUSEOVER); fn2("MOUSEDOWN"); // NG
  15. FOVN จࣈྻ஋Λ࢖ͬͨ৔߹ʹ͸ਖ਼͘͠FOVNʹఆٛ͞Ε͍ͯΔ஋ͷνΣοΫΛߦ ͍·͢ ·ͨ஋Λܕͱͯ͠࢖͏͜ͱͰ5BHHFE6OJPOͱͯ͠΋࢖͏͜ͱ͕Ͱ͖·͢

  16. enum EventType { CLICK = 'CLICK', MOUSEOVER = 'MOUSEOVER'; }

    interface ClickEvent { type: EventType.CLICK; } interface MouseDownEvent { type: EventType.MOUSEOVER; } declare const clickEvent: ClickEvent; declare const mouseDownEvent: MouseDownEvent; const fn3 = (event: ClickEvent) => { return event; } fn3(clickEvent); // OK fn3(mouseDownEvent); // NG
  17. FOVN FOVN͸ศརͰ͕͢ɺ਺஋ͷ৔߹͸ܕ͚ͩͰ͸੍ޚͰ͖ͳ͍ͷͰɺ ਺஋ͱͯ͠ར༻͢Δ৔߹͸ݺͼग़͞ΕΔଆͰൣғͷνΣοΫΛ͠·͠ΐ͏ɻ

  18. /BNFTQBDF OBNFTQBDF΋5ZQF4DSJQUಠࣗػೳͰ͕͢ &4.PEVMFTͷ͓͔͛Ͱ༨Γ࢖͏ҙຯ͸ͳ͘ͳΓ·ͨ͠ ͜ͷػೳ͸એݴϑΝΠϧҎ֎Ͱ࢖͏ͷ͸ࠞཚͷݩͳͷͰ࢖͏ඞཁ͸ͳ͍Ͱ ͠ΐ͏

  19. /VMMPSVOEFpOFE KBWBTDSJQUʹ͸ͭͷແޮͳ஋͕͋Γ·͢ OVMMͱVOEFpOFEͰ͢ VOEFpOFE͸஋͕ະఆٛͷ৔߹ʹར༻͞ΕɺOVMM͸݁Ռ͕ଘࡏ͠ͳ͍࣌ʹ࢖ ΘΕ·͢ ͕ͦͷ࢖͍෼͚ʹରͨ͠ҙຯ͸͋Γ·ͤΜ ࠞཚ͢Δ͚ͩͰ͢

  20. *O5ZQF4DSJQU OVMM΍VOEFpOFE͸5ZQF4DSJQU্Ͱ΋΍΍໘౗Ͱ͢ TUJSDU/VMM$IFDLT͸0/ʹ͢΂͖Ͱ͕͢ɺVOEFpOFEͷνΣοΫ͸͞Ε·ͤΜ

  21. .BZCFPS0QUJPOBM OVMMɺVOEFpOFE͸XSBQͯ͠͠·͍·͠ΐ͏ɹ

  22. type Optional<T> = T | undefined | null;

  23. 0QUJPOBM ຊདྷ0QUJPOBM͸Ϋϥεʹͯ͠͠·͍͍ͨͱ͜ΖͰ͕͢ 5ZQF4DSJQUͰ0QUJPOBM$IBJOJOH͕ೖΔͷͰ ΑΓ5ZQF4DSJQUωΠςΟϒͰऔΓѻ͑Δϑϥοτͳܕͷ΄͏͕ྑ͍Ͱ͠ΐ͏

  24. type Optional<T> = T | undefined | null; declare const

    obj: Optional<{value?: string}>; // ·ͩಈ͖·ͤΜ // or obj?.value || ‘’ // force obj!.value!
  25. ࣮૷

  26. %FWFMPQXJUI5ZQF4DSJQU 5ZQF4DSJQUΛ࢖ͬͯ։ൃ͢Δ৔߹ͷ࣮૷खॱ͸KBWBTDSJQUͱ͸େ͖͘ม͑· ͠ΐ͏

  27. *OUFSGBDF'JSTU ࠷΋େࣄͳ͜ͱ͸ந৅తͳ࣮૷Λ࠷ॳʹߦ͏͜ͱͰ͢ ͦΕ͸ͭ·Γ۩ମతͳϩδοΫ͔Β཭ΕΔ͜ͱͰ͢ 5ZQF4DSJQU͸JOUFSGBDFͱUZQFʹΑͬͯͦΕΛՄೳʹ͍ͯ͠·͢ ِ3FEVYΈ͍ͨͳྫΛ঺հ͠·͢

  28. interface Todo { id: string; date: Date; title: string; done:

    boolean; } type Todos = Todo[]; interface State { todos: Todos; } type Payload = { type: "ADD", } | { type: "DELETE" payload: {id: string}; } const reducer = (payload: Payload, state: State): State => { return state; }
  29. -PHJDJTMBUFS SFEVDFSͷ࣮૷Ҏ֎͸શͯܕͷΈͰ࣮૷͞Ε͍ͯ·͢ SFEVDFS΋த਎͸ۭͰ஋Λฦ͚ͩ͢Ͱ͢ ͔͜͠͠ΕͰϓϩάϥϜͷࠎ͸Ͱ͖͍ͯ·͢ ͋ͱ͸SFEVDFSͷ࣮૷ʹूத͢Δ͚ͩͰ͢

  30. -PHJDJTMBUFS ۃ୺ͳ࿩۩ମతͳΞϧΰϦζϜ͸͋·ΓॏཁͰ͸͋Γ·ͤΜ σʔλߏ଄ɾܕ͕΋ͬͱ΋ॏཁͰ͢ ͕ܾ͜͜·Ε͹େ֓ΞϧΰϦζϜ͸ࣗવͱಋ͔Ε·͢

  31. ڥք

  32. 7JSUVBMBOE3FBM ࠷ॳʹड़΂ͨΑ͏ʹ5ZQF4DSJQU͸͋͘·ͰԾ૝ͷܕΛ࣋ͭݴޠͰ͢ ͦͷͨΊɺ࣮ࡍʹ࣮ߦ͞ΕΔ৔߹ʹ͸஋ͱܕͷဃ཭͕ى͖ΔՄೳੑ͕͋Γ· ͢

  33. 4FQBSBUFE8PSME ಛʹဃ཭͕ى͖΍͍͢ͷ͕ɺ֎෦ͱͷڥքͱͳΔ෦෼Ͱ͢ "1*αʔόͱͷڥք ϒϥ΢βετϨʔδͱͷڥք

  34. "EBQUFS ͨͩ͠ɺٯʹݴ͑͹͜ΕΒͷڥք͑͞཈͑ͯɺઌఔͷJOUFSGBDFઌߦͷ࣮૷ Λߦ͑͹ဃ཭Λ΁Β͢͜ͱ͕Ͱ͖ΔͷͰ͸ͳ͍Ͱ͠ΐ͏͔ʁ ·ͨ1SPUP#VGͷΑ͏ͳ54ࣗಈੜ੒ܥΛ࢖͏ͷ΋खͰ͢

  35. 1SPHSBN 1SPHSBN 1SPHSBN "EBQUFS &YUFSOBM*OUFSGBDF

  36. $MFBO"SDIJUFDUVSF ·ΔͰ$MFBO"SDIJUFDUVSFͷϨΠϠʔਤͷΑ͏ʹͳΓ·ͨ͠ ͔͠͠ɺผʹ$MFBO"SDIJUFDUVSFΛར༻͠Ζͱݴ͍ͬͯΔΘ͚Ͱ͸ͳ͘ 5ZQF4DSJQUͷԾ૝ܕͱ͍͏࢓૊Έʹͱͬͯ΋"EBQUFS͸ඇৗʹॏཁͳҙຯΛ ࣋ͪ·͢ ͲΜͳΞʔΩςΫνϟΛ࠾༻͍ͯͯ͠΋֎෦γεςϜڥքΛਖ਼͘͠཈͑Δ͜ ͱͰɺ5ZQF4DSJQUͷܕ͸ΑΓҰ૚໾ཱͭͰ͠ΐ͏

  37. 5P5ZQFE ࠓ·Ͱͷ࿩͸࠷ॳ͔Β5ZQF4DSJQUͰ։ൃ͍ͯ͠ΔέʔεΛલఏͱ͍ͯ͠·͢ ͕ ΋͠طଘͷKBWBTDSJQU͔ΒҠߦ͢Δ৔߹΋֎෦ڥք͔ΒܕΛ෇͚͍ͯ͘ͱΑ ͍Ͱ͠ΐ͏ ·ͨɺਖ਼͍͔ͨ͠ͱਖ਼͘͠ͳ͍ܕΛڥքΛه࿥͓ͯ͘͜͠ͱ͕େࣄͰ͢

  38. "OZBEBQUFS ܕ෇͚͞Ε͍ͯͳ͍ةݥͳྖҬ͸શͯɺਖ਼͍͠ܕ͔Βม׵ͨ͠ͱ͍͏໨ҹΛ ͚͓ͭͯ͘ͱϦϑΝΫλϦϯά͕͠΍͍͢Ͱ͢

  39. type UncheckedFixme<T> = any; interface Model {} const unTypedFn =

    (a: UncheckedFixme<Model>) { }
  40. "OZBEBQUFS 6ODIFDLFE'JYNF5͕ͲΜͲΜίʔυͷίΞྖҬʹԡ͠ࠐ·ΕΔ·ͰϦ ϑΝΫλϦϯά͚ͭͮ͠·͠ΐ͏ ͦͯ͠࠷ޙʹ͸ίʔυத͔Βফͯ͠͠·͍·͠ΐ͏ ͜ͷΑ͏ͳ#PUUPN6Qతͳܕͷ෇͚ํΛ͢Δͱɺ֎෦ͷةݥͳྖҬ͔Β҆શ ͳ಺෦΁ഭ͍ͬͯ͘ͷͰܕͷϛε͕ى͖ͮΒ͍Ͱ͢ ͪͳΈʹ6ODIFDLFE'JYNF5͸-JOUΤϥʔग़ΔՄೳੑ͕͋ΔͷͰ௵͓ͯ͠ ͍͍ͯͩ͘͞

  41. ίʔσΟϯά

  42. 5ZQFJTCPUIFS ܕ෇͚͸݁ߏ໘౗Ͱ͢ ࠷ॳʹJOUFSGBDFͰܕఆٛΛͪΌΜͱ͓ͯ͘͠ͱزจ͔ղফ͸͞Ε·͕͢ ຊ࣭తʹ෇Ճతͳ࡞ۀͳͷͰαϘΓ͕ͪͰ͢

  43. .BZCFXSPOH ͨͩɺܕ෇͚ͷ໘౗͘͞͞͸ίʔυͷ·͔ͣ͞΋͠Ε·ͤΜ

  44. class Test { private value: {[key: string]: string} | null;

    constructor() {} public setValue(value: {[key: string]: string}) { this.value = value; } public doSomething() { return this.value!['key'] // you need to through type check. } }
  45. *OJUJBMJ[FMBUFS ͜ͷΑ͏ͳޙʹॳظԽ͞ΕΔϝϯόม਺౳͸ܕͰදݱ͢Δͷ͕ࠔ೉Ͱ͢ ͞Βʹ/VMMBCMF͔VOEFpOFEΛڐ༰͢Δܕʹͨ͠৔߹ʹ͍͍ͪͪ Λॻ͘ͷ΋ةݥ͔ͭ໘౗Ͱ͢ ͜ͷΑ͏ͳɺͦ΋ͦ΋ܕͰදݱ͢Δͷ͕೉͍͠ίʔυΛආ͚ΔΑ͏ʹ͢Δͷ ͕ྑ͍Ͱ͢ ࠓճͷέʔεͰݴ͑͹શͯDPOTUSVDUPSͰॳظԽ͢΂͖Ͱ͢

  46. function getValue() { let value: {[key: string]: number} | null

    = null; if (x) { value = {key: 1}; } else { value = {value: 1}; } return value; }
  47. *OJUJBMJ[FMBUFS JGจͷதͰม਺ΛॳظԽ͢ΔͷΛ͚ͯ͞ɺJGจΛؔ਺Խͯ͠͠·͍·͠ΐ͏

  48. .PSFUZQBCMFDPEF ΑΓγϯϓϧʹܕ෇͚Ͱ͖Δίʔυ͸ ਓؒʹ΋ಡΈ΍͘͢ཧղ͠΍͍͢ίʔυͱͳΓ·͢ ΋ͪΖΜ͖Ε͍ʹॻ͍ͯ΋ෳࡶͳܕΛ࣋ͭέʔε͸͋Γ·͢͠ɺશ͕ͯͦͷ ͱ͓ΓͰ͸͋Γ·ͤΜ͕ ෳࡶͳܕػೳΛ࢖͏લʹίʔυͷߏ଄͕ਖ਼͍͔֬͠ೝͯ͠Έ·͠ΐ͏

  49. ·ͱΊ 5ZQF4DSJQUͰͷ։ൃʹ͍ͭͯͷτʔΫͰͨ͠ ͜ΕΒͷ5JQT͕͋ͳͨͷ։ൃͷखॿ͚ʹͳΔͱ޾͍Ͱ͢ ͝ਗ਼ௌ͋Γ͕ͱ͏͍͟͝·ͨ͠