Slide 1

Slide 1 text

3ZVTFJ4BKJLJ!TBKJLJY ΞϓϦจݴͷύʔεͰֶͿ จࣈྻ-JUFSBMܕύζϧೖ໳

Slide 2

Slide 2 text

4BKJ3ZVTFJ4BKJLJ 'SPOUFOE%FWFMPQFSBU$ZCP[V JOD 𝕏 !TBKJLJY

Slide 3

Slide 3 text

ΞϓϦจݴ؅ཧ͋Δ͋Δ

Slide 4

Slide 4 text

1MBDFIPMEFS͋Γͷจݴʹ஋Λ౉ͯ͠ॻࣜԽ จݴϦιʔε͸͜Μͳײ͡ ֤ݴޠ෼༻ҙ͞ΕͯΔ ར༻͢Δͱ͖͸͜Μͳײ͡ ग़ྗHello, Saji / Saji͞Μɺ͜Μʹͪ͸ t("greeting", {name: "Saji"}) {"greeting": "Hello, {{name}}"} // en {"greeting": "{{name}}͞Μɺ͜Μʹͪ͸"} //ja

Slide 5

Slide 5 text

ࠔΔ͜ͱ 1MBDFIPMEFSͷLFZΛؒҧ͑ͯ΋࣮ߦ࣌·Ͱؾ͚ͮͳ͍ ˠ"namae"ʹͳͬͯΔʂ😱 1MBDFIPMEFSͷ਺͸Մม͚ͩͲશ෦ࢦఆ͔ͨ͠΋ࣗ৴͕࣋ͯͳ͍ ˠͦ΋ͦ΋͜ͷจݴLFZͬͯ1MBDFIPMEFS͋ΔΜ͚ͩͬʜʁ ˠ͜ΕͰࢦఆ͠๨Εͳ͍ΑͶʜʁ t("greeting", {namae: "Saji"}) ʙʙʙʙʙ

Slide 6

Slide 6 text

ݡ͍54͞ΜͳΒਪ࿦ͯ͠΄͍͠🥺 ࢦఆ͢΂͖1MBDFIPMEFS͕଍Γͳ͍ؒҧͬͯͨΒΤϥʔʹͳͬͯ΄͍͠ ˠ࣮ߦ࣌ͰͷΤϥʔΛ௿ݮ͍ͨ͠ ͳΜͳΒࣗಈͰ1MBDFIPMEFSʹ౉͢΂͖σʔλΛਪ࿦ͯ͠΄͍͠ ˠʮOʯ·ͰଧͬͨΒʮOBNFʯ͕༧ଌ͞Εͯཉ͘͠ͳ͍ʁ Ͱ΋จݴ͸ͨͩͷจࣈྻͳΜͩΑͳʜ🤨

Slide 7

Slide 7 text

ͬͯ͜ͱ͸ จࣈྻͷύʔε͕ඞཁ

Slide 8

Slide 8 text

ͱݴ͏Θ͚Ͱຊ୊

Slide 9

Slide 9 text

JOGFS5FNQMBUF-JUFSBM5ZQF࠶ؼܕ ͜ͷͭΛ૊Έ߹ΘͤΔͱ൚༻తͳจࣈྻͷύʔεͬΆ͍ॲཧ͕૊ΊΔ จݴͷ1MBDFIPMEFSΛղੳ͢Δ͜ͱͩͬͯͰ͖Δ😍 ࠓճͷϢʔεέʔε 1MBDFIPMEFSͱͯ͠จݴ಺Ͱએݴͨ͠LFZΛղੳͯ͠ॻࣜԽ͢Δࡍʹඞཁͳσ ʔλͷܕΛਪ࿦͍ͨ͠ɻ "Hello, {{name}}" { name: string }

Slide 10

Slide 10 text

*OGFS 5FNQMBUF-JUFSBM5ZQFT ࠶ؼܕ

Slide 11

Slide 11 text

*OGFS 5FNQMBUF-JUFSBM5ZQFT ࠶ؼܕ

Slide 12

Slide 12 text

*OGFS $POEJUJPOBMUZQFT JOGFS͸$POEJUJPOBM5ZQFTͷதͰ࢖͑Δػೳ extendsͷӈลͷதͰʮ͜͜ͷܕɺ໊લ͚ͭͯ࢖͍͍ͨʯͱݴ͑Δػೳ ྫϢʔςΟϦςΟܕͷ1BSBNFUFST ؔ਺ͷҾ਺Λਪ࿦͢Δ ͷ࣮૷ args ෦෼ͷܕΛ1ܕͱ͢Δˠ1Λฦ͢ˠҾ਺ͷܕΛҾ͖ग़ͤͨͶʂ T extends (...args: infer P) => any ? P : never;

Slide 13

Slide 13 text

*OGFS 5FNQMBUF-JUFSBM5ZQFT ࠶ؼܕ

Slide 14

Slide 14 text

5FNQMBUF-JUFSBM5ZQFT +BWB4DSJQUͷ5FNQMBUF-JUFSBMͱಉ͡ߏจͰɺܕΛੜ੒ɾਪ࿦ͯ͘͠ΕΔ 6OJPOͷ෼഑ͱ͔΋ͯ͘͠ΕΔ type World = 'world'; type Greeting = `hello ${World}`; // type Greeting = "hello world" type Ts = 'ts'; type Js = 'js'; type Config = `config.${Ts | Js}`; // type Config = 'config.ts' | 'config.js';

Slide 15

Slide 15 text

*OGFS 5FNQMBUF-JUFSBM5ZQFT ࠶ؼܕ

Slide 16

Slide 16 text

JOGFS5FNQMBUF-JUFSBM5ZQFT *OGFSΛ5FNQMBUF-JUFSBM5ZQFT಺Ͱ࢖͏ͱɺࢦఆͨ͠จࣈྻύλʔϯʹ͓͚Δ ಛఆͷ෦෼Λܕͱͯ͠ൈ͖ग़͢͜ͱ͕Ͱ͖Δʂ T extends `${infer TBefore}.js` T extends `${infer TBefore}.js` ? TBefore : never; AKTAͷલͷ෦෼Λ5#FGPSFܕ ͱͯ͠ൈ͖ग़ͤͱݴ͏ҙຯ

Slide 17

Slide 17 text

ͱ͍͏͜ͱ͸1MBDF)PMEFS෦෼͕ൈ͖ग़ͤΔ ҎԼͷΑ͏ʹɺ\\^^Ͱғ·ΕͨதΛJOGFS͢Ε͹ʜ ˞খٕA\TUSJOH^AΛ࢖͏ͱʮ೚ҙͷจࣈྻܕʯΛදͤΔʂ 1MBDF)PMEFS಺෦ͷจࣈྻΛ51)ܕͱͯ͠ൈ͖ग़ͤͨʂ T extends `${string}{{${infer TPH}}}${string}` ? TPH : never;

Slide 18

Slide 18 text

͋Εɺ΋͏Ͱ͖ͯͳ͍ʁ

Slide 19

Slide 19 text

1MBDFIPMEFS͕ෳ਺ͷ࣌ΛߟྀͰ͖ͯͳ͍🙅 ෳ਺ͷ1MBDFIPMEFS͕͋Δ৔߹࠷ॳͷ෦෼ {{title}} ͔͠औΓग़ͤͯͳ͍ ̍ݸ໨ͷ1MBDF)PMEFSΑΓޙΖ͸Ұݸͷจࣈྻͱͯ͠ਪ࿦͞ΕͪΌͬͯΔ

Slide 20

Slide 20 text

શऔಘ͢Δʹ͸Ͳ͏͠Α͏ʁ🤔 )FMMP \\UJUMF^^ \\OBNF^^ ͜ͷ෦෼Ͱ΋͏̍ճ1MBDFIPMEFSΛ୳͍ͨ͠ ͱ͍͏͔ɺݟ͔ͭΒͳ͘ͳΔ·Ͱ܁Γฦ͍ͨ͠ ͭ·Γɺ಺෦Ͱಉ͡ॲཧ͕ݺͼଓ͚ΒΕΕ͹ʜ FYUFOET ͷӈล `${string}{{${infer TPH}}}${string}` ࣮ࡍͷ จࣈྻ

Slide 21

Slide 21 text

͜Εͬͯ࠶ؼॲཧͰ͸

Slide 22

Slide 22 text

*OGFS 5FNQMBUF-JUFSBM5ZQFT ࠶ؼܕ

Slide 23

Slide 23 text

࠶ؼܕ ͋Δܕͷఆٛ಺Ͱࣗ෼ࣗ਎ͷܕΛݺͼग़͍ͯͯ͠͠Δܕͷ͜ͱ $POEJUJPOBM5ZQFTͱ࠶ىܕΛ૊Έ߹ΘͤΔͱɺʮFYUFOETͷӈล৚݅Λຬͨ͢ ݶΓಉ͡ॲཧ ਪ࿦ Λ܁Γฦ͢ʯ͜ͱ͕Ͱ͖Δ type DeepStringObject = { [key: string]: DeepStringObject | string; }; type Recursive = T extends Condition ? Recursive : never;

Slide 24

Slide 24 text

*OGFS 5FNQMBUF-JUFSBM5ZQFT ࠶ؼܕ

Slide 25

Slide 25 text

࠶ؼܕΛ࢖ͬͯ࠷ޙ·Ͱύʔε͢Δ ޙΖͷจࣈྻʹରͯ͠1MBDF)PMEFS͕͍ͳ͘ͳΔ·Ͱ୳͠ଓ͚͍ͨ ˠޙΖͷจࣈྻΛTAfterͱ͠ɺ·ͨࣗ਎ͷܕʹ౉ͤ͹͍͍ ࠷ऴతʹ͸$POEJUJPOBM5ZQFTͷʮʯҎ߱ ۭ഑ྻ ߦ͖ண͘ऴྃ৚݅ type GetPlaceholderKeys = T extends `${string}{{${infer TPH}}}${infer TAfter}` ? [TPH, …GetPlaceholderKeys] : [];

Slide 26

Slide 26 text

શ෦ͷ1MBDF)PMEFSΛൈ͖ग़ͤͨʂ ଘࡏ͢Δ1MBDFIPMEFSͷLFZΛ഑ྻͰൈ͖ग़ͤͨʂ🎉 ͋ͱ͸{[key] : string}ͷܕʹϚοϐϯάͰ͖Ε͹ྑ͍ɻ

Slide 27

Slide 27 text

վྑ\TUSJOH^ͷܗʹ w 1MBDFIPMEFSͷܕ 51) ΛLFZͱ͢Δ{[key] : string}ͷܕΛ࡞Δ w ࠶ىతʹݺͼग़ͨ݁͠ՌΛަࠩܕͰܨ͛Δ type GetPlaceholderOption = T extends `${string}{{${infer TPH}}}${infer TAfter}` ? { [K in TPH]: string; } & GetPlaceholderOption : {};

Slide 28

Slide 28 text

΍ͬͨͥʂ🎉

Slide 29

Slide 29 text

ͪͳΈʹ͜ΕΛॻࣜԽؔ਺ʹదԠ͢Δͱʜ จࣈྻϦςϥϧܕ͔Β1MBDFIPMEFSͷ෼͚ͩLFZ͕ੜ͑ΔΦϒδΣΫτͷܕΛ ੜ੒Ͱ͖ͨͷͰ as const͞Ε͍ͯΔจݴϦιʔε`RESOUCES`͕͋Δͱ͢Δͱʜ type TranslateFunc = < T extends keyof typeof RESOURCES, >( key: T, params: GetPlaceholderOption<(typeof RESOURCES)[T]>, ) => string;

Slide 30

Slide 30 text

ͪΌΜͱܕౖ͕ͬͯ͘Εͨʂ👮 nameͰͳ͘namaeΛLFZʹͪ͠Όͬͨ࣌ ͪΌΜͱname͔ฉ͍ͯ͘Δ Name ͚ͩࢦఆͨ࣌͠ ͪΌΜͱ`title`͕଍Γͳ͍ΑౖͬͯΒΕΔ

Slide 31

Slide 31 text

ࠓճ঺հͨ͠ख๏ͷ൚༻ੑ ࠓճ͸จࣈྻΛA\\^^AͰғ·ΕΔ෦෼ͱͦͷޙͷͭʹ෼͚ͯಡΈਐΊͨ Ͳ͏ಡΈਐΊΔ͔͸JOGFSͱ5FNQMBUF-JUFSBM5ZQFTͷ૊Έ߹Θͤ࣍ୈ w ҰจࣈͣͭಡΜͰ͍͘͜ͱ΋Ͱ͖Δ w ಛఆͷه߸΍༧໿ޠ͚ͩಡΈਐΊΔ͜ͱ΋Ͱ͖Δ w ࠶ؼͱ৚݅෼ذΛ૊Έ߹ΘͤΔ͜ͱ΋Ͱ͖Δ ͭ·Γେମͷ1BSTFS5PLFOJ[FS͸ॻ͚ͦ͏ͩͶʂ

Slide 32

Slide 32 text

·ͱΊͱԠ༻ JOGFSͱ$POEJUJPOBM5ZQFTͱ࠶ؼܕΛ૊Έ߹ΘͤΔͱ൚༻తͳจࣈྻͷύʔ εͬΆ͍ॲཧ͕૊ΊΔ ͳͷͰจݴͷ1MBDFIPMEFSΛղੳ͢Δ͜ͱ΋Ͱ͖·ͨ͠🎉 ࠓճͷίʔυ͕ࢼͤΔ1MBZHSPVOE΋༻ҙͨ͠ͷͰ৮ͬͯΈͯͶ ࠓճͷྫҎ֎ʹ΋Ԡ༻ྫ͸͋ΔͷͰνϟϨϯδͯ͠ΈΑ͏ʂ w ྫΫΤϦจࣈྻͷղੳQBUIͷղੳ࢛ଇԋࢉϓϩάϥϜॲཧܥ

Slide 33

Slide 33 text

3ZVTFJ4BKJLJ!TBKJLJY ͋Γ͕ͱ͏͍͟͝·ͨ͠