Lock in $30 Savings on PRO—Offer Ends Soon! ⏳

はてなリモートインターンシップ2022 フロントエンドブートキャンプ 講義資料

Hatena
December 19, 2022

はてなリモートインターンシップ2022 フロントエンドブートキャンプ 講義資料

Hatena

December 19, 2022
Tweet

More Decks by Hatena

Other Decks in Programming

Transcript

  1. : React 1. TypeScript JavaScript 2. Web 3. Web html

    4. (accessibility, a y) TypeScript - TypeScript Deep Dive #hatenaintern
  2. : React ˝ Web ˝ ˝ (accessibility, a y) ⪮⛮氳מעלֹס׻ֹמ㵚瓀׊יַׂס

    ־յꝧ氦ס孱׿כ⪦מ釤יַ׀ױ׌ն #hatenaintern
  3. : React React JavaScript html > ls index.html main.js <!--

    index.html --> <html> <head> <script type="module" src="main.js"></script> </head> </html> #hatenaintern
  4. : React React/TypeScript <!-- index.html --> <html> <head> <script type="module"

    src="main.tsx"></script> </head> <body> <div id="root"></div> </body> </html> // main.tsx const App = () => { const user: User | null = useUser() return ( <div> Α͏ͦ͜ɺ{user?.name ?? 'ήετ'}͞Μɻ </div> ) } const container = document.getElementById('root') const root = createRoot(container!) root.render(<App />) #hatenaintern
  5. : React TypeScript JavaScript const user = useUser() TypeScript const

    user: User | null = useUser() jsx jsx const label = () => (<div>...</div>) HTML ES ?. ?? => JSX TypeScript JavaScript Null (??) - JavaScript | MDN (?.) - JavaScript | MDN JSX React #hatenaintern
  6. عٚ٤تقٜؕ 僃二ס乃嫎ך傴ַגؤ٭غ؅㛡ׂס⹿ַ梪㗞⹿ַهٚؗاםלך׵ Ⳃׂ׻ֹמ⹿ַ鋗嫎׫㚺䬵׌׾׆כ Null (??) const hello = (name) =>

    `hello, ${name ?? "ήετ"}!` hello("hatena") // > hello, hatena! hello() // > hello, ήετ! #hatenaintern
  7. عٚ٤تقٜؕ ES (ES ) Null (??) ES var hello =

    function hello(name) { return "hello, " + (name !== null && name !== void 0 ? name : "ήετ") + "!" } hello("hatena") // > hello, hatena! hello() // > hello, ήετ! #hatenaintern
  8. ص٭ٜزؘؕ٤ 3 (Rome , Deno ) عٚ٤تقؕٚ Babel (JavaScript) SWC

    (Rust) esbuild (Golang) ف٤غٚ Webpack Rollup Parcel (SWC) Snowpack, Vite (esbuild) https://deno.land/ https://rome.tools #hatenaintern
  9. Web Chrome, IE, Safari, Firefox Web API JavaScript(ECMAScript) HTML DOM

    API CSS API poly ll JavaScript transpile 2021 | gihyo.jp Web standards ( ) - MDN Web Docs : | MDN #hatenaintern
  10. Web هٚؗاׇכסئَ٭ع敯媲ע♓┖סئؕعך澬鏀׌׾׆כֿך׀ױ׌ն MDN https://developer.mozilla.org/ja/docs/Web MDN Can I use https://caniuse.com mozilla

    Google Open Web Docs https://opencollective.com/open-web-docs/updates/ introducing-open-web-docs #hatenaintern
  11. (accessibility, a y) ( HTML) alt (Tab ) HTML -

    | MDN Semantics ( ) - MDN Web Docs : | MDN #hatenaintern
  12. JavaScript ( min) ES (ES ) JavaScript JavaScript JavaScript ·

    JavaScript Primer #jsprimer #hatenaintern
  13. 1/2 // ม਺ͱએݴ var a = "a" // ม਺ʢάϩʔόϧʣ let

    b = "b" // ม਺ʢϩʔΧϧʣ const c = "c" // ఆ਺ /* ஫ҙ * var Λ༻͍ͨม਺એݴ͸ɺ window ΦϒδΣΫτΛ্ॻ͖ͯ͠͠·͏ */ var console = null console.log("xxx") // Error: window.console is null const id = "1234" // string const name = null // null const age = 2022 // number const isAdmin = false // boolean // object const user = { id, username: name age, isAdmin, memo, } user.age // 2022 // ະఆٛϓϩύςΟͩͱ undefined ͕ฦΔ user.abc #hatenaintern
  14. 2/2 // ؔ਺ function getUser(id) { return db.users.find(id) } const

    getBlog = (id) => { return db.blogs.find(id) } // ഑ྻ const array1 = [1, 2] const array2 = new Array(1, 2) // ഑ྻॲཧ for (elm in array1) { console.log(elm) } array2.forEach((elm) => { console.log(elm) }) array1.map((elm) => elm * 2) // [2, 4] array2.at(0) // 1 #hatenaintern
  15. Arrow Function ˝ function׷return؅✳؂׍מ꞊丗؅榟䡗ך׀׾ ˝ 㓹儖氳מע׆ס亠嫎ך꞊丗؅榟䡗׊יֽׄףـُ׼םַ const hello = (name)

    => `Hello, ${name}` hello("world") // hello, world 1 () Tips: () const getProps = () => ({ a: "foo", b: "bar" }) this Arrow Function #hatenaintern
  16. Arrow Function ˝ 䌕丗ֿ邾丗ֵ׾㕙⺬ע()ך㍱ֹ ˝ ꞊丗⫂ס鋗鳭ֿ邾丗车מ峚׾כ׀ע{}כreturn؅榫ַ׾ const hello = (name,

    lang) => { if (lang === "ja") return `͜Μʹͪ͸ɺ${name}` if (lang === "es") return `Hola, ${name}` return `Hello, ${name}` } #hatenaintern
  17. Promiseמחַי Pending( ) (resolve) Fulfilled (reject) Rejected Fulfilled Rejected (

    ) Settled then catch const sleep = (ms) => new Promise((resolve) => { setTimeout(() => resolve(ms), ms) }) sleep(1000) .then((ms /* resolveͨ͠஋Λड͚औΕΔ */) => console.log(`sleep: ${ms}ms`)) .catch((e) => { console.error(e) }) #hatenaintern
  18. fetch؅✳זג❆ fetch HTTP API Promise Promise console / /* Ϣʔβʔ৘ใΛऔಘ͢ΔAPIͷྫɻҎԼͷΑ͏ͳJSON͕ฦͬͯ͘Δͱ͍͏૝ఆɻ

    { user: {id: 1, name: 'hatena'} } */ const promise = fetch("https://api.example.com/user/1") .then((res) => res.json()) .then((json) => json.user) .then((user) => { console.log(`${user.name}ͷid͸${user.id}`) }) .catch(console.error) console.log(promise) // Promise {<pending>} ɾɾɾ ᶃ #hatenaintern
  19. Promise Promiseס鿥⮛؅⛼䡗׊յא׿؅䣽ֹ׆כך䴧⛍氳ם┾⮛⭚杼؅车ֹ׆כֿ⭳全׾ն const promises = urls.map((url) => fetch(url)) // ෳ਺ͷAPIͳͲΛฒྻʹୟ͘

    Promise.all() Resolve( ) 1 Reject Promise.allSettled() Resolve Reject Promise Promise: {status: 'fulfilled', value: resolveͨ͠஋}, Promise: {status: 'rejected', reason: reject͞ΕͨΤϥʔ} #hatenaintern
  20. Promise const promises = [ getFromCache(), // cache͕ۭͷͱ͖͸ࣦഊ͢Δ getFromApi(), ]

    Promise.race() 1 Promise Resolve Reject Promise.any() Resolve Promise Reject #hatenaintern
  21. async/await async function await Promise try {} catch (e) {}

    async function throw const getUser = async (id) => { try { const res = await fetch(`https://api.example.com/user/${id}`) const json = await res.json() const user = json.user console.log(`${user.name}ͷid͸${user.id}`) return user } catch (e) { console.error(e) throw new Error("error reason: *********") } } ECMAScript Top-level await async function await #hatenaintern
  22. async/await async function Promise Promise then Promise await getUser(1) .then(console.log)

    // {id: 1, name: 'hatena'} .catch(console.error) ˝ 扛⺲꞊丗כ׊י㲔车׌׾׆כ׵׵ה؀؆⭳全׾ ;(async () => { const user = await getUser(1) console.log(user.name) // 'hatena' })() #hatenaintern
  23. class ES class class Rect { constructor(width, height) { this.width

    = width this.height = height } // getter΍setterΛఆٛͰ͖Δ get area() { return this.getArea() } getArea() { return this.width * this.height } } const rect = new Rect(5, 10) console.log(rect.area) // 50 function class https://developer.mozilla.org/en-US/docs/Web/JavaScript/Inheritanceandtheprototypechain #hatenaintern
  24. ECMAScript Modules ٓةٖ٭ٜ 1 == 1 import/export CommonJS Node.js ECMAScript

    Node.js Babel 1 webpack JavaScript ECMAScript JavaScript ECMAScript JavaScript ( ) module.exports require https://nodejs.org/docs/latest/api/modules.html #hatenaintern
  25. default export // module.js export default function doSomething() {} ˝

    export defaultךؙؠتَ٭ع׌׾כյimport侇מע♳䙫ס⺲ ⯥؅錃㲊ך׀׾ import awesome from "./module" #hatenaintern
  26. (named export) ˝ constך㚺丗㲚銧׌׾כ׀מexport؅♀ⱶ׌׾׆כך⺲⯥♀׀ؙؠتَ٭عֿ⭳ 全׾ // namedModule.js export const logType

    = { error: 'error', log: 'log' }; export const log = (message, type) => { if (type === 'error') return console.error(message); return console.log(message); } export const hello => log('hello'); #hatenaintern
  27. ؕ٤َ٭عס亠嫎מחַי export import { log, hello } from "./namedModule" ˝

    asךٛؾ٭ّ⭳全׾ import { logType as LOGTYPE } from "./namedModule" * as export import * as Logger from "./namedModule" Logger.hello() // 'hello' (webpack TreeShaking ) * as #hatenaintern
  28. for...of (iterable) NodeList Map Set const iterable = [10, 20,

    30] for (const value of iterable) { console.log(value) } #hatenaintern
  29. Nullish coalescing operator ?? JavaScript || const rect = (width:

    number, height?: number) => ({ width: width, height: height || 100, // ߴ͞Λলུͨ͠ͱ͖͸σϑΥϧτ஋Λ༩͑Δ }) rect(50, 0) // {width: 50, height: 100} 0 ''( ) Falsy height 0 ?? null undefined ?? ?? !!0 !!'' boolean false JavaScript false null undefined NaN Falsy boolean true Truthy https://developer.mozilla.org/en-US/docs/Glossary/Falsy JavaScript || Truthy Falsy && Falsy Truthy #hatenaintern
  30. Optional chaining ?. ˝ ؛هةؘؠعֿnull׷undefinedם⺎耆䓪ֵֿ׾כ׀յאס؛هةؘؠعסوٞقطؔ؅⽛שג״מifמ׻׾⮆㹎׷&&מ׻׾湾 礘鍐❫؅傴ׂ䑒釐ֵֿזגն const val = nullOrObject

    && nullOrObject.method() const result = val && val.methodOfReturnValue() ˝ .?؅榫ַ׾כյ⽛צ⭳׊⩕ֿnullױגעundefinedסכ׀עא׿♓꡸סوٞقطؔؓؠجت؅׊םַնױגյאס㕙⺬ע undefinedכ׊י鍐❫׈׿׾ն const result = nullOrObject?.method()?.methodOfReturnValue() nullOrObject׵nullOrObject.method()ס鲭׽⡁ֿ⪦מnullך׵undefinedך׵םַכ׀מյ nullOrObject.method().methodOfReturnValue()ס磵冽؅䐂׼׿׾ն && Falsy null undefined && || Falsy Optional chaining #hatenaintern
  31. Spread Syntax ˝ ...؅✳ֹכ鿥⮛׷؛هةؘؠع؅㷣ꝧ⭳全׾ const sum = (a, b, c,

    d) => a + b + c + d const nums = [1, 2] const copied = [...nums] // த਎Λෳ੡ͨ͠഑ྻΛ࡞ΕΔ const moreNums = [...copied, 5] // [1, 2, 5] sum(...nums, 10) // 18 const obj = { a: 10, b: "foo" } const obj2 = { b: "bar", c: true } // 2ͭҎ্ͷobjectΛmerge͢ΔɻΩʔ͕ॏෳ͍ͯ͠Δ৔߹͸ޙʹॻ͍ͨํͰ্ॻ͖͞ΕΔ const merged = { ...obj, ...obj2 } // {a: 10, b: 'bar', c: true} const getUserConfig = (received) => ({ force: false, allowJs: false, ...received, // σϑΥϧτ஋Λ౉͞Εͨ஋͕͋Ε͹্ॻ͖͢Δ }) #hatenaintern
  32. Rest Parameters ... Spread Syntax 1 // const sum =

    (num1, num2, ...nums) => num1 + num2 + nums.reduce((a, b) => a + b, 0) const numbers = [1, 2, 3] sum(3, ...numbers, 6) // 15 #hatenaintern
  33. TypeScript is JavaScript JavaScript JavaScript node React JavaScript JavaScript API

    Uncaught TypeError: Cannot read property 'foo' of undefined JavaScript Alternative JavaScript TypeScript #hatenaintern
  34. tsc: TypeScript compiler TypeScript TypeScript https://github.com/microsoft/TypeScript TypeScript JavaScript ( )

    --noEmit TypeScript JavaScript JavaScript ( ) JavaScript Babel, esbuild babel @babel/preset-typescript babel enum enum typeof JavaScript ( ) #hatenaintern
  35. 㚺丗㲚銧侇ס㑔ؓؿط٭ب٘٤ // JavaScriptͷ৔߹ const a = 'hello'; // TypeScriptͷ৔߹͸ม਺໊ͱ=ͷؒʹ:Λஔ͍ͯܕΞϊςʔγϣϯΛॻ͘ const

    a: ʲ͜͜ʹܕΞϊςʔγϣϯʳ = 'hello'; // ྫ͑͹ const a: string = 'hello'; ׆׿ׂ׼ַדזג׼䫟鑜׊יׂ׿׾סךյ㲔꤀מע傴־םַ׆כ ׵㛡ַ #hatenaintern
  36. : string, number, boolean, null, undefined 'hello', 12, true, false

    ( ) const a: number = 10 const b: boolean = false const c: string = 11 // Type Error const d: "hello" = "hello" const n: null = null ˝ 鿥⮛ const arr: string[] = ["hello", "world"] const arr2: Array<number> = [1, 2, 3, 5, 8] const arr3: [string, number] = ["year", 2021] // λϓϧ(Tuple)ܕͱ΋ #hatenaintern
  37. JavaScript ? const person: { name: string age: number address?:

    string } = { name: "john", age: 21, } string | undefined JavaScript (Object.keys() ) TypeScript . exactOptionalPropertyTypes tsc #hatenaintern
  38. Union Type ( ) 邾丗ס㑔סַ׍׿־؅嵹ג׌ type Primitive = string |

    number | boolean | undefined | null type Color = "red" | "green" | "blue" | "yellow" | "purple" #hatenaintern
  39. typeof ( " " JavaScript ) 'string', 'number', 'boolean', 'object',

    'function', 'undefined' console.log(typeof "hello world") // 'string' const n = 10 console.log(typeof n) // 'number' const p: Person = { name: "jonh", age: 20 } console.log(typeof p) // 'object' console.log(typeof undefined) // 'undefined' console.log(typeof null) // 'object' console.log(typeof ["a"]) // 'object' #hatenaintern
  40. typeof ˝ 攐מnumber׷stringךֵ׾׆כמ⯆꡾׊גַכ׀מ값⭳ // paddingʹ͸ۭനͷ਺·ͨ͸λϒจࣈͳͲ͕΍ͬͯ͘Δ͜ͱΛ૝ఆͨؔ͠਺ const padLeft = (val: string,

    padding: string | number) => { if (typeof padding === "number") { return " ".repeat(padding) + val } // padding͕numberͰͳ͍ͷͰɺstringͰ͋Δͱਪ࿦͞ΕΔ return padding + val } #hatenaintern
  41. in API type Fish = { name: string swim: ()

    => void } type Bird = { name: string fly: () => void } const move = (x: Fish | Bird) => { if ("swim" in x) { // swim͕༗Δͷ͸FishܕͷΈ return x.swim() } // ͳͷͰɺ͜͜ʹ౸ୡ͢Δͱ͸BirdܕͰ͋Δͱ෼͔Δ return x.fly() } #hatenaintern
  42. Object.hasOwn() 2022/08/18 TypeScript ES Object.hasOwn() const move = (x: Fish

    | Bird) => { if (Object.hasOwn(x, "swim")) { // swim͕༗Δͷ͸FishܕͷΈ͚ͩͲɺ Fish͔ Bird͔ͷͲͪΒ͔Λ൑ఆͰ͖ͳ͍ return x.swim() // error: Property 'swim' does not exist on type 'Fish | Bird'. } ... } Support for Object.hasOwn (lib.d.ts and narrowing) · Issue # · microsoft/TypeScript #hatenaintern
  43. as JavaScript // ܕFooΛ௥Ճ͢Δ type Foo = { bar: number

    piyo: string } const something = (x: Foo) => { // ܕͱͯ͠͸߹͍ͬͯΔ͕ɺϥϯλΠϜ্Ͱͷ࣮ߦ࣌ʹ͸piyo͕undefinedʹͳΔͷͰΤϥʔ͕ى͖Δ return x.piyo.split(",") } var foo = {} as Foo // Fooͱͯ͠ѻ͑ΔΑ͏ʹ͓ͯ͘͠ // ࣮ࡍʹ͸barͳͲ͸ແ͍͕Fooͱͯ͠Ξαʔγϣϯ͍ͯ͠ΔͷͰ౉ͤΔ something(foo) #hatenaintern
  44. const as as const ( readonly ) const a =

    [1, 2, 3] // aͷܕ͸number[]ͱͳΔ const b = [1, 2, 3] as const // bͷܕ͸readonly [1, 2, 3]ͱͳΔ type Pallet = { colors: readonly Color[] } const setPallet = (p: Pallet) => { /* do something */ } const pallet = { colors: ["red"], } // ͜͜ʹ as const Λ෇͚ͳ͍ͱ{ color: string[] }ͱਪ࿦͞ΕͯΤϥʔʹͳΔ setPallet(pallet) #hatenaintern
  45. any ˝ ⛰׼־ס⡁ֿ⪌זיַ׾׆כ؅炐׌նundefined־׼؛هةؘؠ ع־׼꞊丗ױך⛰ֿ⪌זיַי׵荁ַնtscֿ㑔ס吾錞؅׊םַ סךյas⺱喋מ鹴ׄ׼׿׾㕙⺬ע鹴ׄ׾ն let anything: any = {}

    // anyʹ͸ԿͰ΋୅ೖͰ͖Δ anything = () => {} anything = null anything.split(",") // anyͷ৔߹͸ϝιου΋ͳΜͰ΋ࢀরͰ͖Δ #hatenaintern
  46. unknown any any unknown unknown {} | null | undefined

    const getObjectValues = (obj: {}) => Object.values(obj) // ݺͼग़͠ଆ͸unknownͳͷͰ޷͖ͳ஋Λ౉ͤΔ const stringifyForLog = (val: unknown) => { if (val === null || val === undefined) return "(anonymous)" return JSON.stringify(getObjectValues(val)) } #hatenaintern
  47. typeכinterface ˝ typeעؙؕٛؓت ˝ interfaceע؛هةؘؠعמ㑔؅♀ׄ׾⮯ס亠嫎ն ˝ 仴㰆ס׵סמ䏲־׼وٞقطؔ؅鴑ⱶך׀׾סעinterface ˝ ٚؕهֿٚٛ䬠❠׊גinterface؅⮵榫縖ֿ舅榺מ䦡䍖ך׀׾ ˝

    typeע⮯ס⺲⯥؅♀ׄ׾䑒釐ֵֿ׾ ˝ typeכinterfaceס✳ַ⮆ׄעؤ٭غ釨硜םלך荇չם孱孬׷╚䍖ֵֿ׾ סךյ齁מ⪌׿ף齁מ䏼זיׂד׈ַ #hatenaintern
  48. typeכinterface Type Type type Blog = { title: string content:

    string } // NG: Duplicate identifier 'Blog'. type Blog = { tags: string[] } // OK type NewBlog = Blog & { tags: string[] } Interface Interface ES Array at() TypeScript . Array // lib.es5.d.ts interface Array<T> { length: number toString(): string ... } // lib.es2022.array.d.ts interface Array<T> { at(index: number): T | undefined } #hatenaintern
  49. ꞊丗 仴מئ٤وٜךע⛰䈱׵⭳י׀יַ׾ׄלյ䌕丗׷鲭׽⡁ס㑔ס傴׀亠סقذ٭٤גה磆☭׊יֽ׀ױ׌ն const f = (x: string): number => {

    return x.length } // ಛʹreturnΛ͠ͳ͍৔߹͸ฦΓ஋ʹvoidΛࢦఆ͢Δ const a: () => void = () => { console.log("a") } // ΦϓγϣφϧͳҾ਺͸keyʹ?Λ෇͚Δ // ਪ࿦͞ΕΔ΋ͷͰྑ͍ͳΒฦΓ஋ͷܕ͸লུՄ const b = (n?: number) => `${n}` // Rest ParametersΛड͚औΔ৔߹͸͜͏͍͏ײ͡ const c = (...texts: string[]) => { return texts.join("|") } #hatenaintern
  50. (Generics) TypeScript querySelector - Hatena Developer Blog const getJSON =

    <T>(url: string): Promise<T> => { // res.json͸anyͱͳΒͣʹܕҾ਺Ͱ౉͞Εͨ΋ͷͱղऍ͞ΕΔ return fetch(url).then<T>((res) => res.json()) } // ͜͜Ͱusers͸User[]ʹͳΔ const users = await getJSON<User[]>("/api/users") // ͜͜Ͱblogs͸Blog[]ʹͳΔ const blogs = await getJSON<Blog[]>("/api/blogs") #hatenaintern
  51. : extends / const echo = <T extends string>(text: T):

    T => { return text } const a = echo("foo") // a ͷܕ͸ 'foo' const str: string = "foo" const b = echo(str) // b ͷܕ͸ 'string' #hatenaintern
  52. never never void never never ( ) const infiniteLoop =

    (): never => { while (true) {} } strictNullChecking JavaScript undefined #hatenaintern
  53. never؅榫ַג禿糵䓪زؘشؠ ˝ never؅榫ַ׾׆כך㑔؝٭غםלךס禿糵䓪؅زؘشؠך׀׾ type Color = "red" | "yellow" |

    "purple" const magical = (color: Color) => { switch (color) { case "red": return "tomato" case "yellow": return "banana" default: // શͯͷcase͕໢ཏ͞Ε͍ͯΕ͹͜͜ʹ౸ୡ͢Δ͜ͱ͸ͳ͍ // ͜ͷ৔߹͸'purple'͕୅ೖ͞ΕΔՄೳੑ͕͋ΔͷͰɺ੩తղੳ࣌ʹΤϥʔʹͳͬͯݕग़Ͱ͖Δ const val: never = color throw new Error(`"${color}" is not implemented`) } } #hatenaintern
  54. Readonly / ReturnType ˝ Readonlyע؛هةؘؠع׷鿥⮛ס釐碛؅鐆ײ鱮ײ㵠榫מך׀׾ ˝ ⫋䅯氳מע鸵榫׈׿םַ׆כמ嫰䙫 type PersonRo =

    Readonly<Person> ˝ ReturnTypeע꞊丗ס鲭׽⡁㑔כ׊י䐂׾ type Func = () => string type ReturnVal = ReturnType<Func> // ReturnVal͸stringͱղऍ͞ΕΔ #hatenaintern
  55. typeof TypeScript JavaScript const hello = () => "hello" type

    Func = typeof hello type P = ReturnType<Func> // P͸stringͱղऍ͞ΕΔ #hatenaintern
  56. keyof key union type const config = { checkJs: false,

    force: true, } // typeofͰconfigͷܕΛಘͯɺkeyofͰͦͷΦϒδΣΫτͷܕͷΩʔΛྻڍ͢Δ type ConfigKey = keyof typeof config // "checkJs" | "force" const getConfigVal = (key: ConfigKey) => config[key] getConfigVal("ignore") // Τϥʔͱͯ͠ݕग़Ͱ͖Δ #hatenaintern
  57. Indexed Access Types JavaScript [] typeof keyof JavaScript type Person

    = { name: string age: number } type Age = Person["age"] // number const signalColors = ["red", "blue", "yellow"] as const // as const͠ͳ͍ͱstring[]ʹͳΔ // Arrayʹ[number]ͰΞΫηε͢Δͱ഑ྻͷ஋Λྻڍͨ͠ܕΛಘΒΕΔ type Signal = typeof signalColors[number] // 'red' | 'blue' | 'yellow' #hatenaintern
  58. (Intersection Types) 邾丗ס㑔؅磝ײ⺬؂׎י㑔؅榟䡗׌׾ն❆ֻףٗ٭ا٭ס嘤꡾מ 䑴׋יٝتَ٤تס㑔؅㚺ֻ׾㕙⺬ע׆ַֹֹ䚉׋ն type Blog = { title: string;

    domain: string } type Editor = { editable: true; authority: ["edit"] } type Owner = { editable: true; authority: ["edit", "publish"] } type ResponseForEditor = Blog & Editor type ResponseForOwner = Blog & Owner #hatenaintern
  59. Conditional Types JavaScript condition ? trueExpression : falseExpression // JavaScriptͷࡾ߲ԋࢉࢠ

    // SomeType͕OtherTypeΛຬͨͤ͹TrueTypeΛಘΔ SomeType extends OtherType ? TrueType : FalseType; Overloads declare function getID<T extends boolean>( fancy: T ): T extends true ? string : number const stringReturnValue = getID(true) const numberReturnValue = getID(false) const stringOrNumber = getID(Math.random() < 0.5) #hatenaintern
  60. Overloads Overloads function request(url: string): Promise<Response> function request(url: string, onlyIsOk:

    true): Promise<boolean> function request(url: string, onlyIsOk = false) { const promise = fetch(url) if (onlyIsOk) return promise.then((res) => res.ok) return promise } #hatenaintern
  61. Overloads ˝ 㓹儖ע湾ׂ傴ׂס؅✳זיֽׄף荁ַך׌ type f = (x: number) => number

    ˝ ⺱喋ס׆כ؅׆ס׻ֹמ׵傴ׄ׾ type f = { (x: number): number } Overloads type func = { (x: number): number (x: string): string } #hatenaintern
  62. (Virtual) DOM React DOM DOM DOM React DOM DOM UI

    key https://ja.reactjs.org/docs/reconciliation.html Document Object Model HTML XML https://zenn.dev/mizchi/books/ c c f cc c b #hatenaintern
  63. JSX JSX JavaScript <h1 className="hello">My name is Clementine!</h1> React DOM

    HTML class className class JavaScript #hatenaintern
  64. ؠٚتؤ٤َ٭ؾ٤عכ꞊丗ؤ٤َ٭ؾ٤ع React 2 <HelloMessage name="hatena" /> ؠٚتؤ٤َ٭ؾ٤ع class HelloMessage extends

    React.Component { render() { return <div>Hello {this.props.name}</div> } } ꞊丗ؤ٤َ٭ؾ٤ع const HelloMessage = ({ name }) => { return <div>Hello {name}</div> } #hatenaintern
  65. Function Component TypeScript TypeScript JSX .tsx () => JSX.Element React.FC

    type Props = { name: string } const Welcome: React.FC<Props> = ({ name }) => { return <h1>Welcome {name}</h1> } React Component undefined #hatenaintern
  66. Props / 1 type Props = { name: string }

    const Welcome: React.FC<Props> = ({ name }) => { return <h1>Welcome {name}</h1> } ( ) JSX <Welcome name="John" /> // <h1>Welcome John</h1> #hatenaintern
  67. React Fragmentמחַי <> </> React Fragment React Component 1 Element

    <div> 2 React Component const Component = () => { return ( <> <span>hello</span> <br /> <span>͜Μʹͪ͸</span> </> ) } key <React.Fragment> </React.Fragment> #hatenaintern
  68. (State) useState use React (Hooks) const Counter = () =>

    { const [count, setCount] = useState(0) const increaseCount = () => setCount((prevCount) => prevCount + 1) return ( <div> Χ΢ϯτ: {count} <button onClick={increaseCount}>Χ΢ϯτ</button> </div> ) } #hatenaintern
  69. useState useState() 1 2 setter ( ) setter Component DOM

    const [color, setColor] = useState<Color>("red") #hatenaintern
  70. useState setter ˝ 二׊ַ⡁؅峚׌ const [color, setColor] = useState<Color>("red") const

    change2Blue = () => setColor("blue") ˝ 泡⯥ס⡁؅⮵榫׊י二׊ַ⡁؅婊㲊׌׾ const [count, setCount] = useState(0) const increaseCount = () => setCount((prevCount) => prevCount + 1) #hatenaintern
  71. Component alert const Counter = () => { const [count,

    setCount] = useState(0) const increaseCount = () => setCount((prevCount) => prevCount + 1) alert(count) return <div>{/* ུ */}</div> } alert OK #hatenaintern
  72. useEffectס╈ךalert؅⽛ש const Counter = () => { const [count, setCount]

    = useState(0) const increaseCount = () => setCount((prevCount) => prevCount + 1) useEffect(() => { alert(count) }) return <div>{/* ུ */}</div> } Component Component alert alert alert UI UI Component #hatenaintern
  73. useEffectכ❣㰆鿥⮛ 2 ❣㰆؅辐׌鿥⮛؅峚׌ Component useEffect(೚ҙͷॲཧؔ਺, []) state useEffect(೚ҙͷॲཧؔ਺, [state]) state

    Component 2 alert const [countA, setCountA] = useState(0) const [countB, setCountB] = useState(0) useEffect(() => { alert(`conutAͷ஋͕${countA}ʹߋ৽͞Ε·ͨ͠`) }) useEffect(() => { alert(`conutAͷ஋͕${countB}ʹߋ৽͞Ε·ͨ͠`) }) countA countB #hatenaintern
  74. useEffectכ❣㰆鿥⮛ ˝ ❣㰆鿥⮛؅錃㲊׌׾׆כךյא׿ב׿ס❣㰆鿥⮛⫂סַ׍׿־ס⡁ֿ㚺催׈׿גכ׀סײⰜ⛼榫ֿ⽛צ⭳׈׿׾׻ֹמ⭳全׾ const [countA, setCountA] = useState(0) const [countB,

    setCountB] = useState(0) useEffect(() => { alert(`conutAͷ஋͕${countA}ʹߋ৽͞Ε·ͨ͠`) }, [countA]) useEffect(() => { alert(`conutAͷ஋͕${countB}ʹߋ৽͞Ε·ͨ͠`) }, [countB]) [] Component Component DOM ( ) (mount) DOM (unmount) Hooks #hatenaintern
  75. (Custom Hook) use Hook Hooks Component 1 const useGetStatus =

    ({ userId }) => { const [status, setStatus] = useState(null) useEffect(() => { const handler = (user) => { setStatus(user.status) } Api.subscribe(userId, handler) return () => Api.unsubscribe(userId, handler) }) return status } #hatenaintern
  76. thisסتؤ٭وס鷿ַמחַי ˝ function؅榫ַג꞊丗ס㕙⺬ const person = { name: "chris", say:

    function () { setTimeout(function () { console.log(`I'm ${this.name}`) }, 100) }, } person.say() // I'm this window.setTimeout(window ) window https://developer.mozilla.org/en-US/docs/Web/API/WindowOrWorkerGlobalScope/ setTimeout#thethisproblem #hatenaintern
  77. thisסتؤ٭وס鷿ַמחַי Arrow Function const person = { name: "chris", say:

    function () { setTimeout(() => { console.log(`I'm ${this.name}`) }, 100) }, } person.say() // I'm chris #hatenaintern
  78. useState state 二׊ַ⡁؅峚׌כ׀ס蛽כ׊狌 const [count, setCount] = useState(0) const increaseCount

    = () => setCount(count + 1) כ׊י׊ױֹכյ const increaseDouble = () => { increment() increment() } ס׻ֹם׵ס؅⛼זגכ׀מյincreaseDouble؅⽛؆ך׵1׊־㘃ֻםַכַֹ杯霄מ鸿鷔׌׾ך׊׺ֹն #hatenaintern
  79. ꞊丗⫂ס㚺丗تؤ٭وכuseState ❆ֻףյcountֿ5ךֵ׾כ׌׾כ const Component = () => { const [count,

    setCount] = useState(0) // ͜͜Ͱม਺count͸είʔϓ಺Ͱݻఆ͞ΕΔ(5) const increaseCount = () => setCount(count + 1) // ↑Ͱݻఆ͞Εͨcount + 1(=6)ΛsetCountʹ౉͢ const increaseDouble = () => { increment() // ↑Ͱ࡞ͬͨؔ਺ΛݺͿͱɺ6͕setCountʹ౉͞ΕΔ increment() // ͜ͷؔ਺ΛݺͿͱ͖΋ɺ6͕setCountʹ౉͞ΕΔͷͰɺ஋͸6ͷ·· } } #hatenaintern
  80. ؤ٭ٜفشؠ꞊丗؅峚׌亠嫎ך傴׀泡׌ ❆ֻףյcountֿ5ךֵ׾כ׌׾כ const Component = () => { const [count,

    setCount] = useState(0) // ͜͜Ͱม਺count͸είʔϓ಺Ͱݻఆ͞ΕΔ(5) const increaseCount = () => setCount((prevCount) => prevCount + 1) // prevCount͸ݺͼग़࣌͠ͷ௚લͷ஋ const increaseDouble = () => { increment() // ͜͜ͰݺͿͱɺprevCountʹ͸5͕ೖ͍ͬͯΔͷͰɺprevCount+1=6͕setCount͞ΕΔ increment() // ͜͜ͰݺͿͱɺprevCountʹ͸6͕ೖ͍ͬͯΔͷͰɺprevCount+1=7͕setCount͞ΕΔ } } state #hatenaintern
  81. Hooks === Object.is const a = "foo" const b =

    "foo" console.log(a === b) // true const objA = { a: "foo", b: 10 } const objB = { a: "foo", b: 10 } console.log(objA === objB) // true console.log(Object.is(objA, objB)) // false #hatenaintern
  82. ❣㰆鿥⮛מ؛هةؘؠع؅⪌׿׾آ٭تמחַי const config = { theme: "sports" } useEffect(() =>

    { loadConfig(config).then(() => {}) }, [config]) config [config.theme] #hatenaintern
  83. ب٤وٜם㍑鹴瓀 Component const config = { theme: "sports" } function

    Component() { useEffect(() => { loadConfig(config).then(() => {}) }, [config]) } Props #hatenaintern
  84. useMemo useMemo React Hooks 1 Component function WordCount({ children })

    { // text͸stringͳͷͰɺͦͷ··ґଘ഑ྻʹग़དྷΔ const words = useMemo(() => children.split(" "), [text]) useEffect(() => { alert(`୯ޠ਺͸${words.length}Ͱ͢`) }, [words]) } Component children <WordCount>Lorem ipsum dolor sit amet</WordCount> #hatenaintern
  85. useMemo׷useCallback؅榫ַגقنؚ٭ُ٤ ت䷉ャ ˝ useMemo׷useCallbackע⡁׷꞊丗סْٓ⴫מ׻זיuseEffectםלס┘釐ם⽛צ⭳׊؅䤰⯆׌׾׆כמ׻זיقنؚ٭ُ٤ت ס䷉ャ؅僿䏨ך׀׾ ˝ 攐מuseMemoךע❣㰆מ✳؂םַ㕙⺬ך׵յ⭚杼סꄆַ銶畀磵冽؅ْٓ⴫׌׾׆כךٝ٤رٛ٤ء侇סهٞشؠ؅䤰ֻ׾׆כ ׵⭳全׾ function Component

    ({a, b}) => { const resultA = useMemo(() => superDuperHighCostCalculation(a), [a]); const resultB = useMemo(() => superDuperHighCostCalculation(b), [b]); return <> <span>{a}͔ΒʮΊͪΌͪ͘Όॏ͍ܭࢉʯΛͨ݁͠Ռ: {resultA}</span> <span>{b}͔ΒʮΊͪΌͪ͘Όॏ͍ܭࢉʯΛͨ݁͠Ռ: {resultB}</span> </> } #hatenaintern
  86. React Component DOM React ref useRef ref current const textInput

    = useRef(null) const submit = (e) => { e.preventDefault() if (textInput.current.value.length < 100) return alert("101จࣈҎ্͕ඞཁͰ͢") createPost({ body: textInput.current.value }) } return ( <form onSubmit={submit}> <input type="text" ref={textInput} /> </form> ) #hatenaintern
  87. DOM DOM React const [text, setText] = useState("") const submit

    = (e) => { e.preventDefault() if (text < 100) return alert("101จࣈҎ্͕ඞཁͰ͢") createPost({ body: text }) } return ( <form onSubmit={submit}> <input type="text" onChange={(e) => setText(e.target.value)} /> </form> ) #hatenaintern
  88. TypeScript TypeScript JavaScript tsc babel JavaScript JavaScript API babel poly

    ll TS JS babel JavaScript JavaScript webpack JavaScript (bundle) ES Modules 1 JavaScript JavaScript(+sourcemap) minify TS/JS sourcemap 1 webpack Terser TreeShaking #hatenaintern
  89. create-react-app React OK webpack, babel, eslint npm start npm test

    react-scripts create-react-app React create-react-app React #hatenaintern
  90. JavaScript ( ) JavaScript DOM HTML CSS API ECMAScript WHATWG

    HTML Living Standard WHATWG DOM Living Standard W C CSS Speci cations #hatenaintern
  91. ECMAScript JavaScript ECMAScript Ecma International Technical Committee TC https://github.com/tc /ecma

    Living Standard 6 ECMAScript babel tsc poly ll Ecma International C# #hatenaintern
  92. Stage 2 ECMAScript · JavaScript Primer #jsprimer Stage pre x

    API 2 JavaScript Google Chrome Node.js V Safari JavaScriptCore Firefox SpiderMonkey Facebook Hermes #hatenaintern
  93. JavaScript ECMAScript JavaScript ECMAScript location.assign WHATWG HTML Living Standard document.querySelector

    WHATWG DOM Living Standard WHATWG HTML/DOM Living Standard ECMAScript HTML DOM (Node.js ) W C HTML HTML . 399 5 WHATWG 2021 1 29 WHATWG Living Standard W C / : [https://future-architect.github.io/articles/ a/ HTML | ] 2004 Apple Mozilla Opera 3 W C HTML Living Standard #hatenaintern
  94. WHATWG Google Chrome HTML DOM API Google Chrome Apple Moziila

    Chrome : Chrome Platform Status Mozilla : Mozilla Speci cation Positions W C Web Incubator Community Group https://scrapbox.io/pastak-pub/ WebAPI #hatenaintern
  95. W C CSS Speci cations CSS CSS WHATWG W C

    All CSS speci cations #hatenaintern