Slide 1

Slide 1 text

㸜Ⰻ䚍ך噰⻌ַ׵鋅׷ 5ZQF4DSJQU 5ZQF4DSJQU.FFUVQ

Slide 2

Slide 2 text

荈䊹稱➜ –ؿٗٝزؒٝسؒٝآص،倜⼼䎃湡!-*/&吳䒭⠓爡 – 5ZQF4DSJQU娖䎃⼱ֻ׵ְ –2JJUB蔓➂5ZQF4DSJQUةؚDPOUSJCVUJPO侧⡘ – ! չ5ZQF4DSJQUך㘗ⰅꟌպ – "չ侁⻌罏ך5ZQF4DSJQUպ – # չ5ZQF4DSJQUך㘗䱿锷鑫铡պ זו !VIZP@

Slide 3

Slide 3 text

!ⴱ׭גך涫㠡"

Slide 4

Slide 4 text

5ZQF4DSJQU׾⢪ֲאך椚歋 –㸜Ⰻ䚍 ˘ 㘗ؒٓ٦׾嗚⳿׃גغؚ׾劢搫ח꣇־׷ –Ꟛ涪⸬桦˘ 㘗䞔㜠׾欽ְ׋酡㸣ד⸬桦״ֻꟚ涪דֹ׷ 㘗ָسًُؗٝزחז׷ ˟5ZQF4DSJQUדכ؝٦س欰䧭ח㘗䞔㜠כ⢪׻׸זְ

Slide 5

Slide 5 text

5ZQF4DSJQU׾⢪ֲאך椚歋 –㸜Ⰻ䚍 ˘ 㘗ؒٓ٦׾嗚⳿׃גغؚ׾劢搫ח꣇־׷ –Ꟛ涪⸬桦˘ 㘗䞔㜠׾欽ְ׋酡㸣ד⸬桦״ֻꟚ涪דֹ׷ 㘗ָسًُؗٝزחז׷ ˟5ZQF4DSJQUדכ؝٦س欰䧭ח㘗䞔㜠כ⢪׻׸זְ

Slide 6

Slide 6 text

5ZQF4DSJQUך㸜Ⰻ䚍ה؝أز 㸜Ⰻ䚍 㘗ך׋׭ך 㷕统؝أز Ꟛ涪؝أز 넝 搀 • 5ZQF4DSJQUכ㸜Ⰻ䚍׾锃眍〳腉 • 㸜Ⰻ䚍׾♴־׷ --noImplicitAnyך搀⸬⻉ anyas@ts-ignoreזו • 㸜Ⰻ䚍׾♳־׷ VOJPO㘗װ勴⟝㘗זוך崞欽 • 㸜Ⰻ䚍׾넝׭׷קו؝أز׮♳傻 㘗ػؤٕ׾װ׶ֺׅ׷ה؝أػָ䝤⻉

Slide 7

Slide 7 text

㘗ך؝أزػؿؓ٦وٝأ 㸜Ⰻ䚍 㘗ך׋׭ך 㷕统؝أز Ꟛ涪؝أز 넝 搀 const items = { apple: { price: 128, }, orange: { price: 200, taxRate: 0.1 } } const getPriceIncludingTax = (name, taxRate) => { const item = items[name] taxRate = taxRate || item.taxRate if (taxRate == null) throw new Error("OMG") return item.price * taxRate } 㸜Ⰻ䚍搀 !

Slide 8

Slide 8 text

㘗ך؝أزػؿؓ٦وٝأ 㸜Ⰻ䚍 㘗ך׋׭ך 㷕统؝أز Ꟛ涪؝أز 넝 搀 const items: Record = { apple: { price: 128 }, orange: { price: 200, taxRate: 1.1 } } const getPriceIncludingTax = (name: string, taxRate?: number) => { const item = items[name] taxRate = taxRate || item.taxRate if (taxRate == null) throw new Error("OMG") return item.price * taxRate } 㸜Ⰻ䚍⚥ ! !

Slide 9

Slide 9 text

㘗ך؝أزػؿؓ٦وٝأ 㸜Ⰻ䚍 㘗ך׋׭ך 㷕统؝أز Ꟛ涪؝أز 넝 搀 type ItemName = 'apple' | 'orange' const assertIsItemPriceData = >(data: D) => data const items = assertIsItemPriceData({ apple: { price: 128 }, orange: { price: 200, taxRate: 1.1 } }) type Distribute = N extends ItemName ? ((typeof items)[N] extends { taxRate: number } ? (name: N) => number : (name: N, taxRate: number) => number) : never type UtoI = (U extends any ? (arg: U) => void : never) extends (arg: infer I) => void ? I : never type getPriceIncludingTaxFunc = UtoI> const getPriceIncludingTax: getPriceIncludingTaxFunc = ( name: ItemName, taxRate?: number ) => { const item = items[name] as any taxRate = (taxRate || item.taxRate) as number return item.price * taxRate } 㸜Ⰻ䚍넝 ! !

Slide 10

Slide 10 text

5ZQF4DSJQUך㸜Ⰻ䚍ה؝أز 㸜Ⰻ䚍 㘗ך׋׭ך 㷕统؝أز Ꟛ涪؝أز 넝 搀 غٓٝأ׾罋ִ״ֲ • 㸜Ⰻ䚍ָו׸ֻ׵ְ妜׃ְךַ וך玎䏝ך⽬ꤹ䚍׾鏩㺁ׅ׷ךַ • ؝أز׾ו׸ֻ׵ְ䩪ִ׷ךַ • 剑穄湡垥כוֿזךַ 䖓ַ׵54׾㼪Ⰵׅ׷㜥さ

Slide 11

Slide 11 text

5ZQF4DSJQUך㸜Ⰻ䚍ה؝أز 㸜Ⰻ䚍 㘗ך׋׭ך 㷕统؝أز Ꟛ涪؝أز 넝 搀 !ֿךز٦ؙכֿֿדׅ

Slide 12

Slide 12 text

5IJT5BML 㸜Ⰻ䚍ח噰䮶׶׃׋5ZQF4DSJQU錁׾䋒侄׃תׅ! –㸜Ⰻ䚍הךぢֹさְ倯 –⡦ָ㸜Ⰻ䚍׾腘ַׅךַ –וך״ֲח㸜Ⰻ䚍׾㸚׷ךַ

Slide 13

Slide 13 text

㸜Ⰻ䚍ַ׵鋅׷5ZQF4DSJQU 5ZQF4DSJQUכ⨳Ⰻ䚍ך瑎ָ㢳ְ –孡鯪ח㎳׾אֻֿהָדֹ׷anyװasזו –׉׮׉׮㘗ءأذي荈⡤ח׮瑎ָ֮׷ ⵃ⤑䚍娖〷涸穗箮㹋鄲♳ך㉏겗ך׋׭ DG5ZQF4DSJQUךVOTBGFז乼⡲תה׭ ˊ 2JJUB CZ!LHULS ˟⨳Ⰻ䚍 TPVOEOFTT 㘗ثؑحؙ׾鸐׸ל㹋遤儗ח㘗ؒٓ٦ָ饯ֹזְ䚍颵

Slide 14

Slide 14 text

㸜Ⰻ䚍ַ׵鋅׷5ZQF4DSJQU 5ZQF4DSJQUכ⨳Ⰻ䚍ך瑎ָ㢳ְ –孡鯪ח㎳׾אֻֿהָדֹ׷anyװasזו –׉׮׉׮㘗ءأذي荈⡤ח׮瑎ָ֮׷ ⵃ⤑䚍娖〷涸穗箮㹋鄲♳ך㉏겗ך׋׭ ⨳Ⰻ䚍ך瑎׾㝰ֺ㸜Ⰻ䚍׾㸚׷ךכ䧮ղך䕵湡!

Slide 15

Slide 15 text

⡭锑ז׈㸜Ⰻ䚍חֿ׌׻׷ךַ 㘗ءأذيך䠐㄂הכ⨳Ⰻ䚍ך椚锷涸⥂鏾זךד 㸜Ⰻ䚍׾灶㠨ׅ׷ה 㘗ءأذيך䠐㄂ָ搀חז׷ַ׵ ˟植㹋ך鎉铂׾⵸חׅ׷ה椚锷涸⥂鏾הְֲַךכ㣄暟铂זךדָׅ׉ֿכ噰䮶׶ח⯜ׄג⹞䒔׃גֻ׌ְׁ

Slide 16

Slide 16 text

㸜Ⰻ䚍׾㸚׷חכ 㣐⾱⵱ ㎳׾אַזְ㣐⾱⵱ 㘗ءأذيך瑎׾瑱ְ׋㜥さכⴽזךד׉ֿכⴽ鷿孡׾אֽת׃׳ֲ

Slide 17

Slide 17 text

⡦ָ㸜Ⰻ䚍׾腘ַׅךַ ֮׷ְכ䧮ղכוך״ֲח㎳׾אֻךַ

Slide 18

Slide 18 text

BOZ㘗 ! BOZ㘗ך暴䗙 –BOZ㘗ך⦼כ⟣䠐ךⵃ欽ָ〳腉 ⡦׾׃ג׮㘗ؒٓ٦ָ饯ֹזְ –BOZ㘗ך⦼ַ׵䖤׋ⴽך⦼׮BOZ㘗׾䭯א فٗػذ؍،ؙإأ٥ꟼ侧ㄎן⳿׃ך鵤׶⦼זו ⚠ BOZ㘗ך⽬ꤹ䚍 –׮כװ㶷㖈荈⡤ָ㎳ –㎳ָ⠗厩ׅ׷ BOZ寅厩 ˟֮ה㘗䞔㜠ָ#חז׷ךד酡㸣׮⸬ֹתׇ׿

Slide 19

Slide 19 text

BOZ寅厩☠ const obj: any = doSomeMagic(); const res = obj.hello.world(); const num: number = obj; const str: string = obj; function doSomeMagic(){ /* empty */ } BOZ㘗ך㢌侧PCK׾⡲䧭 BOZ㘗ך⦼כוֲ⢪׏ג׮ ؒٓ٦חז׵זְ BOZ㘗׾侧⦼װ俑㶵⴨ה׃ג 䪔׏ג׮ؒٓ٦חז׵זְ

Slide 20

Slide 20 text

BOZ寅厩☠ const obj: any = doSomeMagic(); const res = obj.hello.world(); const num: number = obj; const str: string = obj; function doSomeMagic(){ /* empty */ } ֿךPCK׏ג㢌侧כו׿ז괏ח ⢪׏ג׮ؒٓ٦חז׵זְ׃ 侧⦼ד׮֮׷׃俑㶵⴨ד׮֮ ׷׿أ״XXXXXXXXXXXX 㣐㎳ 寅厩ׁ׸׋㢌侧BOZ寅厩彁 鵤׶⦼כBOZ㘗✳如寅厩 BOZך鄃㹱 儗꟦䊴余䷼

Slide 21

Slide 21 text

BOZ寅厩☠ const obj: any = doSomeMagic(); const res = obj.hello.world(); const num: number = obj; const str: string = obj; function doSomeMagic(){ /* empty */ } 寅厩眔㔲 BOZ㘗ך㢌侧ָ֮׷ أ؝٦فⰋג BOZ׾ꅿ佝׃חׅ׷ה ꬊ䌢ח⽬ꤹ 寅厩ׁ׸׋㢌侧BOZ寅厩彁 ˟BOZכ鸬ꓲ涸חOP*NQMJDJU"OZؒٓ٦׾涪欰ׇׁ׷挿׮⳷䝤

Slide 22

Slide 22 text

BTח״׷㘗ٍؗأز ! BTח״׷㘗ٍؗأزך堣腉 –䒭ך㘗׾ⴽך㘗חتٍؐٝؗأزדֹ׷ ˟㘗䞔㜠ָ㢌׻׷׌ֽկ㹋遤儗כ⡦׮饯ֹזְ ⚠ BTח״׷㘗ٍؗأزך⽬ꤹ䚍 –㎳׾אְג׮؝ٝػ؎ٓח䙫׵׸זְ ˟as constכasؗ٦ٙ٦س׾⢪׏גְ׷ֽוⴽ暟ד㸜Ⰻזךדו׿ו׿⢪ְת׃׳ֲկ

Slide 23

Slide 23 text

BTח״׷㘗ٍؗأزך⢽ const v = getNumberOrString() as string; console.log(v.slice(0, 10)); function getNumberOrString(): number | string { return Math.random() ? "foo" : 123; } number | string㘗ך䒭׾ string㘗חتٍؐٝؗأز

Slide 24

Slide 24 text

BTח״׷㘗ٍؗأزך⢽ const v = getNumberOrString() as string; console.log(v.slice(0, 10)); function getNumberOrString(): number | string { return Math.random() ? "foo" : 123; } 鵤׶⦼OVNCFS]TUSJOHהַ 鎉׏ג׷ֽווְֲׇא׮ TUSJOHד׃׳XXXXXXXX 㣐㎳ BTך鄃㹱㹋遤儗ؒٓ٦

Slide 25

Slide 25 text

BTך䕦갟眔㔲 const v = getNumberOrString() as string; console.log(v.slice(0, 10)); function getNumberOrString(): number | string { return Math.random() ? "foo" : 123; } ㎳ָ㢌侧ח⥂㶷ׁ׸׋ ךד׉׸⟃꣬Ⰻגָ ㎳ך䕦갟眔㔲ח

Slide 26

Slide 26 text

BTח״׷㘗ٍؗأزך⢽ function getAnchorOfNode(node: HTMLElement): HTMLAnchorElement | null { let current: HTMLElement | null = node; while (current) { if (current.tagName === "A") { return current as HTMLAnchorElement; } current = current.parentNode as HTMLElement | null; } return null; }

Slide 27

Slide 27 text

BTח״׷㘗ٍؗأزך⢽ function getAnchorOfNode(node: HTMLElement): HTMLAnchorElement | null { let current: HTMLElement | null = node; while (current) { if (current.tagName === "A") { return current as HTMLAnchorElement; } current = current.parentNode as HTMLElement | null; } return null; } current.parentNodeך㘗׾ Node & ParentNode | nullַ׵ HTMLElement | nullח⥜姻 ؒحآ؛٦أ׾ꤐֽל姻׃ְ

Slide 28

Slide 28 text

BOZהBTךתה׭ –姻׃ְ倯ぢח㘗׾⥜姻ׅ׷׋׭ח⢪ֲֶ –㎳׾㢌侧ח⥂㶷׃׋儗挿ד،ؐز –BOZכװלְ㎳ד׃ַ׮⠗厩ׅ׷

Slide 29

Slide 29 text

וך״ֲח㸜Ⰻ䚍׾㸚׷ךַ

Slide 30

Slide 30 text

㸜Ⰻ䚍׾㸚׷倯岀 㣐⾱⵱ ㎳ח״׷寅厩眔㔲׾杞ֻׅ׷

Slide 31

Slide 31 text

㸜Ⰻ䚍׾㸚׷倯岀 㣐⾱⵱ ㎳ח״׷寅厩眔㔲׾杞ֻׅ׷ ➂꟦ָ顑⟣׾䭯א眔㔲׾杞ֻׅ׷ 㢌侧ח㎳׾⥂㶷׃זְ ⽬ꤹ䚍׾䒭חꟗׄ鴥׭׷㢌侧ٖكٕך姻׃ׁ׾➂ָ䬐⥂ ꟼ侧ך؎ٝة٦ؿؑ٦أד㎳׾אַזְ ⽬ꤹ䚍׾ꟼ侧ⰻחꟗׄ鴥׭׷ꟼ侧ٖكٕך姻׃ׁ׾➂ָ䬐⥂ ׉׸ָ搀椚ז׵

Slide 32

Slide 32 text

㢌侧ח㎳׾⥂㶷׃זְ function getAnchorOfNode(node: HTMLElement): HTMLAnchorElement | null { let current: HTMLElement | null = node; while (current) { if (current.tagName === "A") { return current as HTMLAnchorElement; } current = current.parentNode as HTMLElement | null; } return null; }

Slide 33

Slide 33 text

㢌侧ח㎳׾⥂㶷׃זְ function getAnchorOfNode(node: HTMLElement): HTMLAnchorElement | null { let current: HTMLElement | null = node; while (current) { if (current.tagName === "A") { return current as HTMLAnchorElement; } current = current.parentNode as HTMLElement | null; } return null; } BTך⽬ꤹ䚍ך䕦갟眔㔲 ֿך㘗䓼ⵖָ姻׃ְֿה׾➂꟦ָ⥂鏾ׅ׸ל0, ֿֿכ姻׃ְ

Slide 34

Slide 34 text

ꟼ侧ך؎ٝة٦ؿؑ٦أד㎳׾אַזְ interface Foo { type: 'foo' } function isFoo(obj: any): obj is Foo { return obj != null && obj.type === 'foo' } ♷ִ׵׸׋⡦׵ַך⦼objָ Foo㘗ַוֲַⴻ㹀ׅ׷ꟼ侧

Slide 35

Slide 35 text

ꟼ侧ך؎ٝة٦ؿؑ٦أד㎳׾אַזְ interface Foo { type: 'foo' } function isFoo(obj: any): obj is Foo { return obj != null && obj.type === 'foo' } BOZך䕦갟眔㔲כꟼ侧ⰻⰋג ꟼ侧Ⰻ⡤ך姻׃ׁ׾➂꟦ָ ⥂鏾ׅ׸ל0, ˟勴⟝㘗זו׾ꟼ侧ך㘗ח⢪ֲ㜥さ׮㣐⡤ֿ׸חז׷勴⟝㘗כ䱿锷דֹזְךד

Slide 36

Slide 36 text

תה׭ 䧮ղך顑⟣׾剑㼭ח׃אא㸜Ⰻ䚍׾䖤׷׋׭חכ ㎳ח״׷寅厩眔㔲׾杞ֻׅ׷ ׉׮׉׮㎳כז׷ץֻ鼘ֽ׷

Slide 37

Slide 37 text

'VSUIFS3FBEJOH –侁⻌罏ך5ZQF4DSJQUˊ 2JJUB CZ!VIZP –㸜Ⰻ䚍ך嚊䙀׾䓼ְ鎉衝ד铡ֻ鎸✲ –BOZװBT⟃㢩ך⽬ꤹ䚍׮《׶䪔׏גְתׅ –׀㸜䗰ֻ׌ְׁծֿךز٦ؙךⰻ㺁׾㸚׸ל⹧ⵃ罏דׅ – 5ZQF4DSJQUךABTTFSUTYJT5A㘗כוך״ֲח⽬ꤹזךַ ˊ 2JJUB CZ!VIZP –顑⟣眔㔲׾杞ֻׅ׷הְֲ罋ִ倯׾ك٦أחِ٦ؠ٦㹀纏㘗鶢铂 ך⢪ְ倯׾罋㻊׃׋鎸✲