Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Sign up for free
Menu
Search
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Pricing
Search
Sign in
Sign up for free
プロダクト開発とTypeScript
Search
Sponsored
·
Your Podcast. Everywhere. Effortlessly.
Share. Educate. Inspire. Entertain. You do you. We'll handle the rest.
→
Taketoshi Aono(青野健利 a.k.a brn)
October 02, 2019
Programming
3k
7
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
プロダクト開発とTypeScript
TypeScriptによるプロダクト開発の知見
Taketoshi Aono(青野健利 a.k.a brn)
October 02, 2019
More Decks by Taketoshi Aono(青野健利 a.k.a brn)
See All by Taketoshi Aono(青野健利 a.k.a brn)
document.write再考
brn
7
3.2k
Parsing Javascript
brn
14
9.6k
JSON & Object Tips
brn
1
600
CA 1Day Youth Bootcamp for Frontend LT
brn
0
1.1k
Modern TypeScript
brn
2
890
javascript - behind the scene
brn
3
820
tc39 proposals
brn
0
1k
React-Springでリッチなアニメーション
brn
1
780
javascript internationalization API
brn
0
980
Other Decks in Programming
See All in Programming
アクセシビリティから考える情報設計
high_g_engineer
0
380
LL言語やWebフレームワークのPostgreSQL対応 〜DBの機能がユーザーに届くまで〜
kentaroutakeda
1
150
UnityでSystem.Net.WebSocketsなWebSocketサーバが動かないのでUnity Monoのコードを覗いてみた / about implementing websocket server with unity mono
drumath2237
1
180
新卒PdEのリアル
ryu1013
1
500
Vibes Containers 〜AIで変わるコンテナ設計と運用〜
tkikuc
3
550
『寄り添うラジオ』をAIで作る 体験価値から逆算した、会話しないUXと品質設計
theoriatec2024
3
180
Everything will be SERVERLESS — 信じて運用した10年の経験値 / Everything Will be Serverless — Lessons Learned from 10 Years of Operational Experience
seike460
PRO
1
280
Intent as Code
shoppingjaws
6
1k
What We Talk About When We Talk About XP
m_seki
2
660
TiDB Cloudのカスタムコントローラーによるオートスケール対応
takaidohigasi
0
130
Augmenting AI with the Power of Jakarta EE
ivargrimstad
0
200
iOSDC2026登壇資料.pdf
riofujimon
0
170
Featured
See All Featured
KATA
mclloyd
PRO
35
15k
The Impact of AI in SEO - AI Overviews June 2024 Edition
aleyda
6
1.2k
We Are The Robots
honzajavorek
0
380
Learning to Love Humans: Emotional Interface Design
aarron
275
41k
Accessibility Awareness
sabderemane
1
210
Chrome DevTools: State of the Union 2024 - Debugging React & Beyond
addyosmani
10
1.3k
Large-scale JavaScript Application Architecture
addyosmani
515
110k
HTML-Aware ERB: The Path to Reactive Rendering @ RubyCon 2026, Rimini, Italy
marcoroth
5
690
Six Lessons from altMBA
skipperchong
29
4.5k
Exploring anti-patterns in Rails
aemeredith
4
510
The Director’s Chair: Orchestrating AI for Truly Effective Learning
tmiket
1
300
Exploring the relationship between traditional SERPs and Gen AI search
raygrieselhuber
PRO
3
4.3k
Transcript
Product development with TypeScript
Name !CSO 5BLFUPTIJ"POP੨݈ར Occupation 'SPOUFOE%FWFMPQFS1SPEVDU0XOFS Company $ZCFSBHFOU"EUFDI4UVEJP"*.FTTFOHFS OSS $POUSJCVUPSPG7
About IUUQJOGPCODI
1SPEVDUEFWFMPQFEFGGFDUJWFMZ 5ZQF4DSJQUಋೖͯ͠ϓϩμΫτ։ൃͷੜ࢈ੑ্͕Γ·͔ͨ͠ʁ ಋೖ͚ͨͩ͠Ͱͳ͔ͳ͔͍͔͠͠Ε·ͤΜɻ ࠓͷτʔΫ͕ ੜ࢈ੑΛͰ͖Δ্͚ͩ͛ΔͨΊͷΨΠυͱͳΔ͜ͱΛئ͍·͢ɻ
*NQPSUBOUUIJOHTBCPVU5ZQF4DSJQU 5ZQF4DSJQUͷॏཁͳͰ͢ KBWBTDSJQUͰͳ͍͕KBWBTDSJQUͰ͋Δ ܕ࣮ߦ࣌ʹফ͑Δ
ػೳ
#FGPSFBMM લఏͱͯ͠UTDPOpHKTPOͰҎԼͷػೳඞͣ0/ʹ͠·͠ΐ͏ OP*NQMJDJU"OZ TUSJDU
*NQPSUBOUUIJOHTBCPVU5ZQF4DSJQU KBWBTDSJQUͰͳ͍͕KBWBTDSJQUͰ͋Δ 5ZQF4DSJQUKBWBTDSJQUͷ4VQFS4FUΛᨳ͍ͬͯ·͢ ͦͷͨΊ༷తʹ+BWBTDSJQUΛ౿ऻ͍ͯ͠·͕͢ ͋͘·Ͱผͷݴޠͱଊ͑ͨ΄͏͕ྑ͍Ͱ͢ ͦͷ্Ͱ͍͔ͭ͘ॏཁͳʹ͍͓ͭͯ͠·͢
FOVN FOVN5ZQF4DSJQUͷಠࣗػೳͰ͢ KBWBTDSJQUʹແ͍ͱ͍͏ҙຯࠓޙಉ ͡ҙຯͰ͍·͢
enum Card { SPADE, HEART, DIAMOND, CLUB } // ࿈൪
assert.equal(Card.SPADE, 0); assert.equal(Card.DIAMOND, 2); // ٯҾ͖ assert.equal(Card[Card.DIAMOND], 'DIAMOND');
enum Event { CLICK = 'CLICK', MOUSEOVER = 'MOUSEOVER'; }
FOVN FOVN͜ͷΑ͏ʹΛ·ͱΊΔͷʹར༻͠·͕͢ FOVN͕ࣗܕΛߏ͠ɺܕνΣοΫʹར༻Ͱ͖·͢ ͨͩ͠ҙ͕͋Γ·͢
enum Card { SPADE, HEART, DIAMOND, CLUB } const fn
= (card: Card) => { return card; } fn(Card.SPADE); // OK fn(0); // OK fn(10); // OK
FOVN FOVNΛͦͷ··ར༻͢Δͱɺ୯७ͳOVNCFSܕͱͳΓͷൣғΛνΣο Ϋͯ͘͠Ε·ͤΜ ͦͷͨΊෆਖ਼ͳΛ͢͜ͱՄೳʹͳΓ·͢
enum EventType { CLICK = 'CLICK', MOUSEOVER = 'MOUSEOVER'; }
const fn2 = (event: EventType) => {return event;} fn2(EventType.CLICK); fn2(EventType.MOUSEOVER); fn2("MOUSEDOWN"); // NG
FOVN จࣈྻΛͬͨ߹ʹਖ਼͘͠FOVNʹఆٛ͞Ε͍ͯΔͷνΣοΫΛߦ ͍·͢ ·ͨΛܕͱͯ͠͏͜ͱͰ5BHHFE6OJPOͱͯ͠͏͜ͱ͕Ͱ͖·͢
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
FOVN FOVNศརͰ͕͢ɺͷ߹ܕ͚ͩͰ੍ޚͰ͖ͳ͍ͷͰɺ ͱͯ͠ར༻͢Δ߹ݺͼग़͞ΕΔଆͰൣғͷνΣοΫΛ͠·͠ΐ͏ɻ
/BNFTQBDF OBNFTQBDF5ZQF4DSJQUಠࣗػೳͰ͕͢ &4.PEVMFTͷ͓͔͛Ͱ༨Γ͏ҙຯͳ͘ͳΓ·ͨ͠ ͜ͷػೳએݴϑΝΠϧҎ֎Ͱ͏ͷࠞཚͷݩͳͷͰ͏ඞཁͳ͍Ͱ ͠ΐ͏
/VMMPSVOEFpOFE KBWBTDSJQUʹͭͷແޮͳ͕͋Γ·͢ OVMMͱVOEFpOFEͰ͢ VOEFpOFE͕ະఆٛͷ߹ʹར༻͞ΕɺOVMM݁Ռ͕ଘࡏ͠ͳ͍࣌ʹ ΘΕ·͢ ͕ͦͷ͍͚ʹରͨ͠ҙຯ͋Γ·ͤΜ ࠞཚ͢Δ͚ͩͰ͢
*O5ZQF4DSJQU OVMMVOEFpOFE5ZQF4DSJQU্Ͱ໘Ͱ͢ TUJSDU/VMM$IFDLT0/ʹ͖͢Ͱ͕͢ɺVOEFpOFEͷνΣοΫ͞Ε·ͤΜ
.BZCFPS0QUJPOBM OVMMɺVOEFpOFEXSBQͯ͠͠·͍·͠ΐ͏ɹ
type Optional<T> = T | undefined | null;
0QUJPOBM ຊདྷ0QUJPOBMΫϥεʹͯ͠͠·͍͍ͨͱ͜ΖͰ͕͢ 5ZQF4DSJQUͰ0QUJPOBM$IBJOJOH͕ೖΔͷͰ ΑΓ5ZQF4DSJQUωΠςΟϒͰऔΓѻ͑Δϑϥοτͳܕͷ΄͏͕ྑ͍Ͱ͠ΐ͏
type Optional<T> = T | undefined | null; declare const
obj: Optional<{value?: string}>; // ·ͩಈ͖·ͤΜ // or obj?.value || ‘’ // force obj!.value!
࣮
%FWFMPQXJUI5ZQF4DSJQU 5ZQF4DSJQUΛͬͯ։ൃ͢Δ߹ͷ࣮खॱKBWBTDSJQUͱେ͖͘ม͑· ͠ΐ͏
*OUFSGBDF'JSTU ࠷େࣄͳ͜ͱநతͳ࣮Λ࠷ॳʹߦ͏͜ͱͰ͢ ͦΕͭ·Γ۩ମతͳϩδοΫ͔ΒΕΔ͜ͱͰ͢ 5ZQF4DSJQUJOUFSGBDFͱUZQFʹΑͬͯͦΕΛՄೳʹ͍ͯ͠·͢ ِ3FEVYΈ͍ͨͳྫΛհ͠·͢
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; }
-PHJDJTMBUFS SFEVDFSͷ࣮Ҏ֎શͯܕͷΈͰ࣮͞Ε͍ͯ·͢ SFEVDFSதۭͰΛฦ͚ͩ͢Ͱ͢ ͔͜͠͠ΕͰϓϩάϥϜͷࠎͰ͖͍ͯ·͢ ͋ͱSFEVDFSͷ࣮ʹूத͢Δ͚ͩͰ͢
-PHJDJTMBUFS ۃͳ۩ମతͳΞϧΰϦζϜ͋·ΓॏཁͰ͋Γ·ͤΜ σʔλߏɾܕ͕ͬͱॏཁͰ͢ ͕ܾ͜͜·Εେ֓ΞϧΰϦζϜࣗવͱಋ͔Ε·͢
ڥք
7JSUVBMBOE3FBM ࠷ॳʹड़ͨΑ͏ʹ5ZQF4DSJQU͋͘·ͰԾͷܕΛ࣋ͭݴޠͰ͢ ͦͷͨΊɺ࣮ࡍʹ࣮ߦ͞ΕΔ߹ʹͱܕͷဃ͕ى͖ΔՄೳੑ͕͋Γ· ͢
4FQBSBUFE8PSME ಛʹဃ͕ى͖͍͢ͷ͕ɺ֎෦ͱͷڥքͱͳΔ෦Ͱ͢ "1*αʔόͱͷڥք ϒϥβετϨʔδͱͷڥք
"EBQUFS ͨͩ͠ɺٯʹݴ͑͜ΕΒͷڥք͑͑ͯ͞ɺઌఔͷJOUFSGBDFઌߦͷ࣮ Λߦ͑ဃΛΒ͢͜ͱ͕Ͱ͖ΔͷͰͳ͍Ͱ͠ΐ͏͔ʁ ·ͨ1SPUP#VGͷΑ͏ͳ54ࣗಈੜܥΛ͏ͷखͰ͢
1SPHSBN 1SPHSBN 1SPHSBN "EBQUFS &YUFSOBM*OUFSGBDF
$MFBO"SDIJUFDUVSF ·ΔͰ$MFBO"SDIJUFDUVSFͷϨΠϠʔਤͷΑ͏ʹͳΓ·ͨ͠ ͔͠͠ɺผʹ$MFBO"SDIJUFDUVSFΛར༻͠Ζͱݴ͍ͬͯΔΘ͚Ͱͳ͘ 5ZQF4DSJQUͷԾܕͱ͍͏Έʹͱͬͯ"EBQUFSඇৗʹॏཁͳҙຯΛ ࣋ͪ·͢ ͲΜͳΞʔΩςΫνϟΛ࠾༻͍ͯͯ͠֎෦γεςϜڥքΛਖ਼͑͘͠Δ͜ ͱͰɺ5ZQF4DSJQUͷܕΑΓҰཱͭͰ͠ΐ͏
5P5ZQFE ࠓ·Ͱͷ࠷ॳ͔Β5ZQF4DSJQUͰ։ൃ͍ͯ͠ΔέʔεΛલఏͱ͍ͯ͠·͢ ͕ ͠طଘͷKBWBTDSJQU͔ΒҠߦ͢Δ߹֎෦ڥք͔ΒܕΛ͚͍ͯ͘ͱΑ ͍Ͱ͠ΐ͏ ·ͨɺਖ਼͍͔ͨ͠ͱਖ਼͘͠ͳ͍ܕΛڥքΛه͓ͯ͘͜͠ͱ͕େࣄͰ͢
"OZBEBQUFS ܕ͚͞Ε͍ͯͳ͍ةݥͳྖҬશͯɺਖ਼͍͠ܕ͔Βมͨ͠ͱ͍͏ҹΛ ͚͓ͭͯ͘ͱϦϑΝΫλϦϯά͕͍͢͠Ͱ͢
type UncheckedFixme<T> = any; interface Model {} const unTypedFn =
(a: UncheckedFixme<Model>) { }
"OZBEBQUFS 6ODIFDLFE'JYNF5͕ͲΜͲΜίʔυͷίΞྖҬʹԡ͠ࠐ·ΕΔ·ͰϦ ϑΝΫλϦϯά͚ͭͮ͠·͠ΐ͏ ͦͯ͠࠷ޙʹίʔυத͔Βফͯ͠͠·͍·͠ΐ͏ ͜ͷΑ͏ͳ#PUUPN6Qతͳܕͷ͚ํΛ͢Δͱɺ֎෦ͷةݥͳྖҬ͔Β҆શ ͳ෦ഭ͍ͬͯ͘ͷͰܕͷϛε͕ى͖ͮΒ͍Ͱ͢ ͪͳΈʹ6ODIFDLFE'JYNF5-JOUΤϥʔग़ΔՄೳੑ͕͋ΔͷͰ௵͓ͯ͠ ͍͍ͯͩ͘͞
ίʔσΟϯά
5ZQFJTCPUIFS ܕ͚݁ߏ໘Ͱ͢ ࠷ॳʹJOUFSGBDFͰܕఆٛΛͪΌΜͱ͓ͯ͘͠ͱزจ͔ղফ͞Ε·͕͢ ຊ࣭తʹՃతͳ࡞ۀͳͷͰαϘΓ͕ͪͰ͢
.BZCFXSPOH ͨͩɺܕ͚ͷ໘͘͞͞ίʔυͷ·͔ͣ͞͠Ε·ͤΜ
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. } }
*OJUJBMJ[FMBUFS ͜ͷΑ͏ͳޙʹॳظԽ͞ΕΔϝϯόมܕͰදݱ͢Δͷ͕ࠔͰ͢ ͞Βʹ/VMMBCMF͔VOEFpOFEΛڐ༰͢Δܕʹͨ͠߹ʹ͍͍ͪͪ Λॻ͘ͷةݥ͔ͭ໘Ͱ͢ ͜ͷΑ͏ͳɺͦͦܕͰදݱ͢Δͷ͕͍͠ίʔυΛආ͚ΔΑ͏ʹ͢Δͷ ͕ྑ͍Ͱ͢ ࠓճͷέʔεͰݴ͑શͯDPOTUSVDUPSͰॳظԽ͖͢Ͱ͢
function getValue() { let value: {[key: string]: number} | null
= null; if (x) { value = {key: 1}; } else { value = {value: 1}; } return value; }
*OJUJBMJ[FMBUFS JGจͷதͰมΛॳظԽ͢ΔͷΛ͚ͯ͞ɺJGจΛؔԽͯ͠͠·͍·͠ΐ͏
.PSFUZQBCMFDPEF ΑΓγϯϓϧʹܕ͚Ͱ͖Δίʔυ ਓؒʹಡΈ͘͢ཧղ͍͢͠ίʔυͱͳΓ·͢ ͪΖΜ͖Ε͍ʹॻ͍ͯෳࡶͳܕΛ࣋ͭέʔε͋Γ·͢͠ɺશ͕ͯͦͷ ͱ͓ΓͰ͋Γ·ͤΜ͕ ෳࡶͳܕػೳΛ͏લʹίʔυͷߏ͕ਖ਼͍͔֬͠ೝͯ͠Έ·͠ΐ͏
·ͱΊ 5ZQF4DSJQUͰͷ։ൃʹ͍ͭͯͷτʔΫͰͨ͠ ͜ΕΒͷ5JQT͕͋ͳͨͷ։ൃͷखॿ͚ʹͳΔͱ͍Ͱ͢ ͝ਗ਼ௌ͋Γ͕ͱ͏͍͟͝·ͨ͠