TypeScript 4.9のas const satisfiesが便利
by
tonkotsuboy_com
Link
Embed
Share
Beginning
This slide
Copy link URL
Copy link URL
Copy iframe embed code
Copy iframe embed code
Copy javascript embed code
Copy javascript embed code
Share
Tweet
Share
Tweet
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 αςΟεϑΝΠζʢˈTUɪˌ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-JTUHSFFOVOLOPXOͳͷͰɺྻͷ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-JTUHSFFOOVNCFS<>ʹਪ͞ΕΔͷͰɺྻͷ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ాதܕ͕ͩɺOBNFTUSJOHܕʹ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Ͱ࠷৽ϑϩϯτΤϯυٕज़Λൃ৴͍ͯ͠·͢