Upgrade to Pro — share decks privately, control downloads, hide ads and more …

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

Avatar for Hatena Hatena
December 19, 2022

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

Avatar for Hatena

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