Slide 1

Slide 1 text

5ZQF4DSJQUͷ BTDPOTUTBUJT fi FT͕ศར ϚωʔϑΥϫʔυࣛ໺૖ 5FDI'FFE&YQFSUT/JHIUʙ+BWB4DSJQU5ZQF4DSJQU࠷લઢ

Slide 2

Slide 2 text

ࣛ໺૖!UPOLPUTVCPZ@DPN ϚωʔϑΥϫʔυϏδωεΧϯύχʔ 
 ܦཧࡒ຿ϓϩμΫτຊ෦ϓϩμΫτ։ൃ෦෭෦௕

Slide 3

Slide 3 text

ࣥචɿ+BWB4DSJQUίʔυϨγϐू

Slide 4

Slide 4 text

ࣥචɿ೔ܦιϑτ΢ΣΞ

Slide 5

Slide 5 text

ࠓ೔఻͍͑ͨ͜ͱ

Slide 6

Slide 6 text

BTDPOTUTBUJTGJFTΛ࢖͏ͱɺ XJEFOJOHͷ๷ࢭͱ ܕਪ࿦݁Ռͷอ͕࣋Ͱ͖Δ

Slide 7

Slide 7 text

BTDPOTUTBUJTGJFT

Slide 8

Slide 8 text

BTDPOTUTBUJTGJFT

Slide 9

Slide 9 text

TBUJTGJFTͱ͸ʁ 01

Slide 10

Slide 10 text

satisfiesͱ͸ 式 satisfies 型 w ͕ࣜܕʹϚον͢Δ͔Ͳ͏͔ʁΛνΣοΫ͢Δ w 5ZQF4DSJQUͰಋೖ͞Εͨ IUUQTEFWCMPHTNJDSPTPGUDPNUZQFTDSJQUBOOPVODJOHUZQFTDSJQU

Slide 11

Slide 11 text

satisfiesͷൃԻɾҙຯ ൃԻ w αςΟεϑΝΠζʢˈT‘UɪˌTGBɪ[ʣ ҙຯ w ຬ଍ͤ͞Δɺຬͨ͢ w TBUJTGZʹࡾ୯ݱͷT͕͍ͭͨܗ

Slide 12

Slide 12 text

satisfiesͷಈ࡞ ಲࠎେֶ͕TUSJOHܕʹϚον͢Δ͔Ͳ͏͔ʁ0, ͕TUSJOHܕʹϚον͢Δ͔Ͳ͏͔ʁ/( const foo = "豚⾻⼤学" satisfies string; const foo = 14 satisfies string;

Slide 13

Slide 13 text

satisfiesͷಈ࡞ type Person = { age: number name: string } const myPerson = { age: 18, name: ["ラーメン", "うどん"] } satisfies Person; type Person = { age: number name: string } const myPerson = { age: 18, name: "千賀" } satisfies Person; OBNF͕TUSJOH͡Όͳ͍ͷͰ/( 0,

Slide 14

Slide 14 text

2ܕ஫ऍͱԿ͕ҧ͏ͷʁ🤔 "ਪ࿦݁ՌΛอ࣋͢Δ͔Ͳ͏͔

Slide 15

Slide 15 text

ܕ஫ऍͱsatisfies type MyType = { foo: string; }; // 型注釈 const object1: MyType = { foo: "HELLO", }; // satisfies const object2 = { foo: "HELLO", } satisfies MyType;

Slide 16

Slide 16 text

ܕ஫ऍͷ৔߹ DPMPS-JTUHSFFO͸VOLOPXOͳͷͰɺ഑ྻͷNBQ ؔ਺͸࢖͑ͳ͍ type ColorList = { [key in "red" | "green" | "blue"]: unknown; }; const colorList: ColorList = { red: "#ff0000", green: [0, 255, 0], blue: "#00ffff", }; // unknownなのでNG colorList.green.map((value) => value * 2);

Slide 17

Slide 17 text

satisfiesͷ৔߹ DPMPS-JTUHSFFO͸OVNCFS<>ʹਪ࿦͞ΕΔͷͰɺ഑ྻͷNBQ ؔ਺͕࢖͑Δ type ColorList = { [key in "red" | "green" | "blue"]: unknown; }; const colorList = { red: "#ff0000", green: [0, 255, 0], blue: "#00ffff", } satisfies ColorList; // number[]なのでOK colorList.green.map((value) => value * 2);

Slide 18

Slide 18 text

TBUJTGJFT͸ɺܕνΣοΫ͠ͳ͕Β΋ ܕਪ࿦݁ՌΛอ࣋Ͱ͖Δ

Slide 19

Slide 19 text

BTDPOTUΛ૊Έ߹ΘͤΔͱศར

Slide 20

Slide 20 text

BTDPOTU 02

Slide 21

Slide 21 text

BTDPOTUTBUJTGJFT

Slide 22

Slide 22 text

as constͱ͸ ࣜBTDPOTU ࢀߟɿϓϩΛ໨ࢦ͢ਓͷͨΊͷ5ZQF4DSJQUೖ໳ʢٕज़ධ࿦ࣾʣCZ!VIZP@ • 5ZQF4DSJQUͰಋೖ • จࣈྻɾ਺஋ɾਅِ஋ͳͲͷϦςϥϧܕΛXJEFOJOH͠ͳ͍ • ΦϒδΣΫτ಺ͷ͢΂ͯͷϓϩύςΟ͕SFBEPOMZʹͳΔ • ഑ྻϦςϥϧͷਪ࿦݁Ռ͕λϓϧܕʹͳΔ

Slide 23

Slide 23 text

widening: Ϧςϥϧܕ͕ϓϦϛςΟϒܕʹ֦େ // "ラーメン"型 const food: "ラーメン" = "ラーメン"; // 「20」型 const age: 20 = 20; // 推論結果は"⽥中"型 const name = "⽥中"; // 推論結果はtrue型 const isValid = true; ϓϦϛςΟϒܕ // string型 const food: string = "ラーメン"; // number型 const age: number = age; // 推論結果はstring型 let name = "⽥中"; Ϧςϥϧܕ

Slide 24

Slide 24 text

wideningͷى͜Δέʔε // nameの推論結果は"⽥中"型 const name = "⽥中"; // name2の推論結果はstring型 let name2 = name; OBNF͸ాதܕ͕ͩɺOBNF͸TUSJOHܕʹXJEFOJOH͞ΕΔ

Slide 25

Slide 25 text

഑ྻͷwidening // 推論結果は string[] const myArray = [ "ラーメン", "うどん", "梅が枝餅" ]; // 値の書き換えができる myArray[0] = "モツ鍋"; NZ"SSBZ͸<ϥʔϝϯ ͏ͲΜ ക͕ࢬṷ>Ͱ͸ͳ͘ɺTUSJOH<>ʹਪ࿦͞ΕΔ

Slide 26

Slide 26 text

ΦϒδΣΫτͷwidening // 推論結果 {age: number, name: string} const myObject = { age: 18, name: "⽥中", }; // 値の書き換えができる myObject.age = 30; NZ0CKFDU͸\BHF OBNFాத^Ͱ͸ͳ͘ɺ 
 \BHFOVNCFS OBNFTUSJOH^ʹਪ࿦͞ΕΔ

Slide 27

Slide 27 text

BTDPOTUΛ͔ͭ͏ͱ XJEFOJOHͷ๷ࢭSFBEPOMZԽ͕Ͱ͖Δ

Slide 28

Slide 28 text

wideningͷ๷ࢭ // nameの推論結果は"⽥中"型 const name = "⽥中" as const; // name2の推論結果も"⽥中"型 let name2 = name; MFUએݴͨ͠OBNF΋ాதܕʹͳΔ

Slide 29

Slide 29 text

഑ྻͷwidening๷ࢭ + readonlyԽ // 推論結果は // ["ラーメン", "うどん", "梅が枝餅"] const myArray = [ "ラーメン", "うどん", "梅が枝餅" ] as const; // 書き換え不可能 myArray[0] = "モツ鍋"; NZ"SSBZ͸λϓϧͷ <ϥʔϝϯ ͏ͲΜ ക͕ࢬṷ>ʹਪ࿦͞ΕΔ

Slide 30

Slide 30 text

ΦϒδΣΫτͷwidening๷ࢭ // 推論結果は {age: 18, name: "⽥中"} const myObject = { age: 18, name: "⽥中", } as const; // 書き換え不可能 myObject.age = 30; NZ0CKFDU͸\BHF OBNFాத^ʹਪ࿦͞ΕΔ

Slide 31

Slide 31 text

ఆ਺ΛFYQPSU͢Δͱ͖͸ ඇXJEFOJOHSFBEPOMZͷ৔߹͕ଟ͍ͷͰ ੵۃతʹBTDPTOUΛ͚ͭΔ͜ͱ͕ଟ͍

Slide 32

Slide 32 text

BTDPOTUͱTBUJTGJFTΛ૊Έ߹ΘͤΔ 03

Slide 33

Slide 33 text

as constͱsatisfiesͷ૊Έ߹Θͤ as const satisfies XJEFOJOH๷ࢭ SFBEPOMZԽ ˓ ʷ ܕνΣοΫ ʷ ˓

Slide 34

Slide 34 text

as constͱsatisfiesͷ૊Έ߹Θͤ as const satisfies as const satisfies XJEFOJOH๷ࢭ SFBEPOMZԽ ˓ ʷ ˓ ܕνΣοΫ ʷ ˓ ˓

Slide 35

Slide 35 text

BTDPOTUTBUJTGJFTͷαϯϓϧ

Slide 36

Slide 36 text

as const satisfiesͷαϯϓϧ type Person = { age: number; name: string; tags: string[]; }; 1FSTPOܕʹϚον͢ΔΦϒδΣΫτΛ࡞Δ

Slide 37

Slide 37 text

BTDPOTUͳ͠ˠXJEFOJOH๷ࢭ❌ TBUJT fi FTͳ͠ˠܕνΣοΫ❌ type Person = { age: number; name: string; }; export const myPerson = { age: "⼆⼗歳", name: "⽥中", };

Slide 38

Slide 38 text

BTDPOTUͳ͠ˠXJEFOJOH๷ࢭ❌ TBUJT fi FTͳ͠ˠܕνΣοΫ❌ OVNCFSܕ͕ೖΔ΂͖͕ͩɺ ܕνΣοΫͰ͖͍ͯͳ͍👎 *%&ͷਪ࿦݁Ռදࣔɻ XJEFOJOH͍ͯ͠Δ👎 type Person = { age: number; name: string; }; export const myPerson = { age: "⼆⼗歳", name: "⽥中", };

Slide 39

Slide 39 text

BTDPOTU͋ΓˠXJEFOJOH๷ࢭ⭕ TBUJT fi FTͳ͠ˠܕνΣοΫ❌ type Person = { age: number; name: string; }; export const myPerson = { age: "⼆⼗歳", name: "⽥中", } as const;

Slide 40

Slide 40 text

BTDPOTU͋ΓˠXJEFOJOH๷ࢭ⭕ TBUJT fi FTͳ͠ˠܕνΣοΫ❌ *%&ͷਪ࿦݁Ռදࣔɻ XJEFOJOH๷ࢭSFBEPOMZ👍 type Person = { age: number; name: string; }; export const myPerson = { age: "⼆⼗歳", name: "⽥中", } as const; OVNCFSܕ͕ೖΔ΂͖͕ͩɺ ܕνΣοΫͰ͖͍ͯͳ͍👎

Slide 41

Slide 41 text

BTDPOTUͳ͠ˠXJEFOJOH๷ࢭ❌ TBUJT fi FT͋ΓˠܕνΣοΫ⭕ type Person = { age: number; name: string; }; export const myPerson = { age: "⼆⼗歳", name: "⽥中", } satisfies Person;

Slide 42

Slide 42 text

type Person = { age: number; name: string; }; export const myPerson = { age: "⼆⼗歳", name: "⽥中", } satisfies Person; BTDPOTUͳ͠ˠXJEFOJOH๷ࢭ❌ TBUJT fi FT͋ΓˠܕνΣοΫ⭕ *%&ͷਪ࿦݁Ռදࣔɻ XJEFOJOH͍ͯ͠Δ👎 OVNCFSܕ͕ೖΔ΂͖ՕॴΛ ܕνΣοΫ͍ͯ͠Δ👍

Slide 43

Slide 43 text

BTDPOTU͋ΓˠXJEFOJOH๷ࢭ⭕ TBUJT fi FT͋ΓˠܕνΣοΫ⭕ type Person = { age: number; name: string; }; export const myPerson = { age: "⼆⼗歳", name: "⽥中", } as const satisfies Person;

Slide 44

Slide 44 text

type Person = { age: number; name: string; }; export const myPerson = { age: "⼆⼗歳", name: "⽥中", } as const satisfies Person; BTDPOTU͋ΓˠXJEFOJOH๷ࢭ⭕ TBUJT fi FT͋ΓˠܕνΣοΫ⭕ *%&ͷਪ࿦݁Ռදࣔɻ XJEFOJOH๷ࢭSFBEPOMZ👍 OVNCFSܕ͕ೖΔ΂͖ՕॴΛ ܕνΣοΫ͍ͯ͠Δ👍

Slide 45

Slide 45 text

BTDPOTU͋ΓˠXJEFOJOH๷ࢭ⭕ TBUJT fi FT͋ΓˠܕνΣοΫ⭕ type Person = { age: number; name: string; }; export const myPerson = { age: 20, name: "⽥中", } as const satisfies Person; मਖ਼ͨ͠ΦϒδΣΫτͰͷ *%&ਪ࿦݁Ռ

Slide 46

Slide 46 text

ίʔυͰͷ׆༻ྫ

Slide 47

Slide 47 text

ΞϓϦέʔγϣϯͷόʔδϣϯ؅ཧఆ਺ export const appVersion = "1.0.2" as const satisfies `${number}.${number}.${number}`;

Slide 48

Slide 48 text

URLͷҰཡΛ؅ཧ export const urlList = { apple: "https://www.apple.com/jp/", google: "https://www.google.com/", yahoo: "https://www.yahoo.co.jp/", } as const satisfies { // 値は https:// で始まるURLに限定する [key: string]: `https://${string}`; };

Slide 49

Slide 49 text

Χϥʔίʔυͷྻڍ export const color = { apple: "#65AB51", black: "#000", // 中略 white: "#FFFFFF", whiteSmoke: "#F7F7F7", } as const satisfies { [key: string]: `#${string}`; };

Slide 50

Slide 50 text

εςʔλεͷ഑ྻ export const statusList = [ { status: "processing", title: "作業中" }, { status: "cancel", title: "キャンセル" }, { status: "completed", title: "完了" }, ] as const satisfies readonly { status: string; title: string; }[];

Slide 51

Slide 51 text

ઃఆϑΝΠϧ export const config = { target: "es2021", cache: { type: "filesystem", }, output: { asyncChunks: true, folder: "dist", }, } as const satisfies MyConfig;

Slide 52

Slide 52 text

·ͱΊ

Slide 53

Slide 53 text

BTDPOTUTBUJTGJFTͰ XJEFOJOH๷ࢭͱ ܕਪ࿦݁Ռͷอ͕࣋Ͱ͖Δ

Slide 54

Slide 54 text

ͱ͘ʹɺఆ਺ΛFYQPSU͢Δ৔߹͸ ࢖͏ਓͷ͜ͱΛߟ͑ͯ BTDPOTUTBUJTGJFT͓ͯ͜͠͏

Slide 55

Slide 55 text

هࣄͰ΋ৄ͘͠ղઆ͍ͯ͠·͢ IUUQT[FOOEFWNPOFZGPSXBSEBSUJDMFTUZQFTDSJQUBTDPOTUTBUJT fi FT

Slide 56

Slide 56 text

Thank y ! @tonkotsuboy_com @matsu_eri 5XJUUFSͰ͸࠷৽ϑϩϯτΤϯυٕज़Λൃ৴͍ͯ͠·͢