2024-03-06.md

๐Ÿก

DIL: ๋ชจ๋˜ ๋ฆฌ์•กํŠธ ๋”ฅ ๋‹ค์ด๋ธŒ, 1์ฃผ์ฐจ-3

์Šคํ„ฐ๋””: ์›”๊ฐ„ CS, https://github.com/monthly-cs/2024-03-modern-react-deep-dive
์˜ค๋Š˜ ์ง„ํ–‰: ๊ฐœ์ธ๊ณต๋ถ€


DIL-week1-3_2024-03-06

| DIL ์ฃผ์ฐจ | ๋ฒ”์œ„ | ๋‚ด์šฉ | ์˜ค๋Š˜์ฐจ ์ง„๋„ | | -------- | ------ | ------------------------------ | ----------- | | 1์ฃผ์ฐจ | 1, 2์žฅ | ๋ฆฌ์•กํŠธ ํ•ต์‹ฌ์š”์†Œ์™€ ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ | 93p~123p |

์˜ค๋Š˜ ์ฝ์€ ๋‚ด์šฉ์„ markdown์œผ๋กœ ๊ฐ„๋‹จํžˆ ๋ฉ”๋ชจ
์ฝ์€ ์‹œ๊ฐ„: 8์‹œ 45๋ถ„~12์‹œ
์˜ค๋Š˜ ๋งŽ์ด ์ฝ์–ด์•ผํ•จ, ๋ชฉํ‘œ 2.x๊นŒ์ง€? => ใ…‡

Array์˜ map, filter, reduce, forEach

  • [ES5]์ด๋‹ˆ๊นŒ ํŠธ๋žœ์ŠคํŒŒ์ผ, ํด๋ฆฌํ•„ ๋ถ€๋‹ด์—†์Œ
  • ๊ธฐ์กด ๋ฐฐ์—ด์˜ ๊ฐ’ ๊ฑด๋“œ๋ฆฌ์ง€ ์•Š์œผ๋ฏ€๋กœ ์•ˆ์ „~
  • ๐Ÿ“Œreduce ํ•œ ์ค„ ์„ค๋ช…: ์ฝœ๋ฐฑํ•จ์ˆ˜์™€ ํ•จ๊ป˜ ์ดˆ๊ธฐ๊ฐ’์„ ์ธ์ˆ˜๋กœ ๋ฐ›๋Š”๋ฐ, ์ดˆ๊ธฐ๊ฐ’์— ๋”ฐ๋ผ ๋ฐฐ์—ด, ๊ฐ์ฒด ๋“ฑ์„ ๋ฐ˜ํ™˜ํ•  ์ˆ˜ ์žˆ๋Š” Array ํ”„๋กœํ† ํƒ€์ž…์˜ ๋ฉ”์„œ๋“œ์ด๋‹ค
// ๊ฐ€๋…์„ฑ์— ์ฃผ๋ชฉ
const result1 = arr.filter((item) => item % 2 === 0).map((item) => item * 100); // ํ•˜์ง€๋งŒ ๋ฐฐ์—ด์„ 2๋ฒˆ ๋ˆ๋‹ค

const result3 = arr.reduce((result, item) => {
  if (item % 2 === 0) result.push(item);
  return result;
}, []);
  • forEach์˜ ํŠน์ง•s
    • ๋ฐ˜ํ™˜๊ฐ’: undefined
    • break, returnํ•ด๋„ ์ˆœํšŒ๋ฅผ ๋ฉˆ์ถœ ์ˆ˜ ์—†์Œ: ๋ฌด์กฐ๊ฑด O(n)
  • ECMAScript
    • https://github.com/tc39/proposals

TypeScript

  • TypeScript is JavaScript with syntax for types.
  • ๋™์  ํƒ€์ž… ์–ธ์–ด์˜ ๋‹จ์ : ์—๋Ÿฌ๋ฅผ ์ฝ”๋“œ๋ฅผ ์‹คํ–‰ํ–ˆ์„ ๋•Œ ํ™•์ธํ•œ๋‹ค
    • => ํƒ€์ž…์Šคํฌ๋ฆฝํŠธ: ํƒ€์ž… ์ฒดํฌ๋ฅผ ์ •์ ์œผ๋กœ ๋Ÿฐํƒ€์ž„์ด ์•„๋‹Œ ๋นŒ๋“œ(ํŠธ๋žœ์ŠคํŒŒ์ผ) ํƒ€์ž„์— ์ˆ˜ํ–‰
  • TypeScript Playground: https://www.typescriptlang.org/play

| ๊ตฌ๋ถ„ | ๊ธฐ๋Šฅ | ์‚ฌ์šฉ ์˜ˆ์‹œ | | --------------- | ----------------------------------- | -------------------------------------------------- | | instanceof | ํŠน์ • ํด๋ž˜์Šค์˜ ์ธ์Šคํ„ด์Šค์ธ์ง€ ํ™•์ธ | ์—๋Ÿฌ ํ•ธ๋“ค๋ง ์‹œ ์‚ฌ์šฉ (HttpError, AxiosError etc...) | | typeof | ํŠน์ • ๊ฐ’์˜ ์ž๋ฃŒํ˜•์ธ์ง€ ํ™•์ธ | ์š”์†Œ์˜ ์ž๋ฃŒํ˜• ์ฒดํฌ | | in | property in object | ์ฃผ๋กœ ์–ด๋–ค ๊ฐ์ฒด์— ํ‚ค๊ฐ€ ์กด์žฌํ•˜๋Š” ํ™•์ธ | | generic | ๋‹จ์ผ ํƒ€์ž…์ด ์•„๋‹Œ ๋‹ค์–‘ํ•œ ํƒ€์ž…์— ๋Œ€์‘ | useState ์„ ์–ธํ•  ๋•Œ ๋งŽ์ด ๋ด„ | | index signature | ํ‚ค์— ์›ํ•˜๋Š” ํƒ€์ž…์„ ๋ถ€์—ฌํ•  ์ˆ˜ ์žˆ๋‹ค | ํƒ€์ž… ๋‹จ์–ธ hello[key as keyof Hello] |

๊ทธ ์™ธ

  • Flow๋ผ๋Š” ์ •์  ํƒ€์ž… ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋„ ์žˆ์—ˆ๋‹ค(ํŽ˜์ด์Šค๋ถ)
    • ๊ธฐ์กด ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ์ฝ”๋“œ์— ์• ๋„ˆํ…Œ์ด์…˜
    • (ํŽ˜์ด์Šค๋ถ) yarn์ด๋‚˜ jest๋„ TS๋กœ ์žฌ์ž‘์„ฑ๋จ
  • (MS) VSC์˜ Definitely Typed
    • @types

unknown

  • top type, type narrowing์ด ํ•„์š”
function doSomething(callback: unknown) {
  if (typeof callback === "function") {
    callback();
    return;
  }

  throw new Error("callback is not a function");
}

never

  • bottom type
  • ์–ด๋””๋‹ค ์“ฐ๋ƒ?
    • class component์—์„œ Props๊ฐ€ ๋น„์—ˆ์Œ์„ ๋‚˜ํƒ€๋‚ผ ๋•Œ type Props = Record<string, never>

Generic

  • ์ œ๋„ˆ๋ฆญ
function multipleGeneric<First, Last>(a1: First, a2: Last): [First, Last] {
  return [a1, a2];
}

const [a, b] = multipleGeneric<stirng, boolean>("true", true);
  • ์ธ๋ฑ์Šค ์‹œ๊ทธ๋‹ˆ์ฒ˜
// type Hello = Record<"hello" | "hi", string>;
type Hello = { [key in "hello" | "hi"]: string };

const hello: Hello = {
  hello: "๐Ÿ‘‹",
  hi: "๐Ÿ–๏ธ",
};
  • key ๋‹จ์–ธ
Object.keys(hello).map((key) => hello[key as keyof Hello]);
  • keysOf ํ—ฌํผ๋ฅผ ๋งŒ๋“ค์–ด์„œ, string[] ๋Œ€์‹  ๊ฐœ๋ฐœ์ž๊ฐ€ ๋‹จ์–ธํ•œ ํƒ€์ž…์œผ๋กœ ๊ฐ•์ œํ•˜๊ธฐ
function keysOf<T extends Object>(obj: T): Array<keyof T> {
  return Array.from(Object.keys(obj)) as Array<keyof T>;
}

keysOf(hello).map((key) => hello[key]);

Object.keys๊ฐ€ string[]์œผ๋กœ ๊ฐ•์ œ๋˜์–ด ์žˆ๋Š” ์ด์œ ?

  • ํƒ€์ž… ์ฒดํฌ๋ฅผ ํ•  ๋•Œ, ๊ทธ ๊ฐ’์ด ๊ฐ€์ง„ ํ˜•ํƒœ์— ์ง‘์ค‘ํ•˜๊ธฐ ๋•Œ๋ฌธ
  • One of TypeScript's core principles in that type checking focuses on the shape that values have. This is sometimes called "duck typing" or "structural subtyping".
  • Exact ํƒ€์ž…์ด ์ƒ๊ธธ ์ˆ˜๋„~?

ํƒ€์ž…์Šคํฌ๋ฆฝํŠธ ์ „ํ™˜ ๊ฐ€์ด๋“œ

  • tsconfig.json
{
  "compilerOptions": {
    "outDir": "./dist",
    "allowJs": true,
    "target": "es5"
  },
  "include": ["./src/**/*"]
}

2.1 JSX

  • ํŠธ๋žœ์ŠคํŒŒ์ผ๋Ÿฌ๋ฅผ ๊ฑฐ์น˜์ง€ ์•Š์œผ๋ฉด ์˜ค๋ฅ˜๊ฐ€ ๋‚˜๋Š” ์ด์œ  > JS ํ‘œ์ค€ ์ฝ”๋“œ๊ฐ€ ์•„๋‹˜
  • ๋ชฉ์ : (1) HTML, XML์„ JS ๋‚ด๋ถ€์— ํ‘œํ˜„ (2) ํŠธ๋ฆฌ ๊ตฌ์กฐ๋ฅผ ํ† ํฐํ™” -(ํŠธ๋žœ์ŠคํŒŒ์ผ)-> ECMAScript๋กœ ๋ณ€ํ™˜
  • XML๊ณผ ๋น„์Šทํ•˜๊ฒŒ ๋ณด์ด๋Š” ์ด์œ ? JS ๊ฐœ๋ฐœ์ž๊ฐ€ ์นœ์ˆ™ํ•˜๊ฒŒ ๋Š๋ผ๊ธฐ ์œ„ํ•ด
  • JS ๋‚ด๋ถ€์—์„œ ํ‘œํ˜„ํ•˜๊ธฐ ๊นŒ๋‹ค๋กœ์› ๋˜ XML ์Šคํƒ€์ผ์˜ ํŠธ๋ฆฌ ๊ตฌ๋ฌธ ์ž‘์„ฑ์„ ๋„์›€

์ •์˜

JSXElement, JSXAttribute, JSXChildren, JSXString

โ–ท JSXElement

  • JSXOpeningElement, JSXClosingElement, JSXAttributes, JSXSelfClosingElement
<JSXOpeningElement JSXAttributes(optional)>
</JSXClosingElement>

<JSXSelfClosingElement JSXAttributes(optional) />

<></>
  • ๋ฆฌ์•กํŠธ ์ปดํฌ๋„ŒํŠธ๋ฅผ ํŒŒ์Šค์นผ๋กœ ๋งŒ๋“ค์–ด์•ผ ํ•˜๋Š” ์ด์œ ?
    • React์—์„œ HTML ํƒœ๊ทธ๋ช…๊ณผ ์‚ฌ์šฉ์ž๊ฐ€ ๋งŒ๋“  ํƒœ๊ทธ๋ช…์„ ๊ตฌ๋ถ„์ง€์œผ๋ ค๊ณ  ํ•œ ๊ฒƒ

JSXElementName

  • JSXIdentifier, JSXNamespacedName, JSXMemberExpression

JSXMemberExpression

| ํŠน์ง• | ์„ค๋ช… | | ------ | ----------------------------------------------------------------------------------------------- | | ์—ญํ•  | ๊ฐ์ฒด์˜ ์†์„ฑ์— ์ ‘๊ทผํ•˜๊ธฐ ์œ„ํ•ด ์‚ฌ์šฉ๋จ | | ํ‘œ๊ธฐ๋ฒ• | ๊ฐ์ฒด์™€ ์†์„ฑ ์‚ฌ์ด์— ์  ํ‘œ๊ธฐ๋ฒ•์„ ์‚ฌ์šฉ (์˜ˆ: object.property) | | ์˜ˆ์‹œ | <Component.foo />์—์„œ Component๋Š” ๊ฐ์ฒด๋ฅผ ๋‚˜ํƒ€๋‚ด๊ณ , foo๋Š” ํ•ด๋‹น ๊ฐ์ฒด์˜ ์†์„ฑ์„ ๋‚˜ํƒ€๋ƒ„ | | ์˜ˆ์ œ | https://codesandbox.io/p/sandbox/mordern-react-deep-dive-t9vlwm?file=%2Fsrc%2FApp.tsx%3A25%2C18 | | ํŠน์ง• | n๊ฐœ ๋ฌถ์„ ์ˆ˜ ์žˆ์œผ๋‚˜ => JSXNamespacedName์™€ ์ด์–ด์„œ๋Š” x |

JSXIdentifier

| ํŠน์ง• | ์„ค๋ช… | | ------ | ----------------------------------------------------------------------------------------------------- | | ์—ญํ•  | ์š”์†Œ ์ด๋ฆ„์ด๋‚˜ ์†์„ฑ ์ด๋ฆ„์„ ๋‚˜ํƒ€๋ƒ„ | | ํ‘œ๊ธฐ๋ฒ• | ์ผ๋ฐ˜์ ์œผ๋กœ ํƒœ๊ทธ ์ด๋ฆ„์ด๋‚˜ ์†์„ฑ ์ด๋ฆ„์„ ๋‚˜ํƒ€๋‚ด๋ฉฐ, ๋„ค์ž„์ŠคํŽ˜์ด์Šค๋ฅผ ์‚ฌ์šฉํ•˜์ง€ ์•Š์Œ | | ์˜ˆ์‹œ | ์—์„œ div๋Š” ์š”์†Œ์˜ ์ด๋ฆ„์„ ๋‚˜ํƒ€๋ƒ„ | | ํŠน์ง• | ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ์˜ ์‹๋ณ„์ž์™€ ๋™์ผํ•˜๊ฒŒ (1)$, _ ์™ธ์˜ ๋‹ค๋ฅธ ํŠน๋ฌธ์œผ๋กœ ์‹œ์ž‘ํ•  ์ˆ˜ ์—†์Œ (2) ์ˆซ์ž๋กœ ์‹œ์ž‘ํ•  ์ˆ˜ ์—†์Œ |

JSXNamespacedName

| ํŠน์ง• | ์„ค๋ช… | | ------ | ---------------------------------------------------------------------------------------- | | ์—ญํ•  | XML ๋„ค์ž„์ŠคํŽ˜์ด์Šค๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์š”์†Œ๋ฅผ ์ •์˜ํ•จ ex) RSS, SVG | | ํ‘œ๊ธฐ๋ฒ• | ๋„ค์ž„์ŠคํŽ˜์ด์Šค์™€ ์š”์†Œ ์ด๋ฆ„ ์‚ฌ์ด์— ์ฝœ๋ก (:)์„ ์‚ฌ์šฉํ•˜์—ฌ ๊ตฌ๋ถ„ํ•จ | | ์˜ˆ์‹œ | <svg:rect />์—์„œ svg๋Š” ๋„ค์ž„์ŠคํŽ˜์ด์Šค๋ฅผ ๋‚˜ํƒ€๋‚ด๊ณ , rect๋Š” ์š”์†Œ์˜ ์ด๋ฆ„์„ ๋‚˜ํƒ€๋ƒ„ (XML ๋„ค์ž„์Šค) | | ํŠน์ง• | 2๊ฐœ ์ด์ƒ์€ ์˜ฌ๋ฐ”๋ฅธ ์‹๋ณ„์ž๋กœ ์ทจ๊ธ‰๋˜์ง€ ์•Š์Œ |

โ–ท JSXAttributes

(optional) JSXSpreadAttribute, JSXAttribute

  • JSXSpreadAttribute: ์ „๊ฐœ ์—ฐ์‚ฐ์ž, {...AssignmentExpression}
  • JSXAttribute: ํ‚ค ๊ฐ’ ์Œ, {JSXAttributeName: JSXAttributeValue}
    • JSXAttributeValue: "๋ฌธ์ž์—ด", '๋ฌธ์ž์—ด', {AssignmentExpression}, JSXElement

โ–ท JSXChildren

JSXChild

  • JSXChild: JSXChildren์€ JSXChild๋ฅผ 0๊ฐœ ์ด์ƒ ๊ฐ€์ง
    • JSXText: {, }, <, > ์ œ์™ธ
    • JSXElement
    • JSXFragment
    • { JSXChildExpression (optional) }
      <>{(() => "๐Ÿ‘")()}</>
      

โ–ท JSXString

  • const message = "This is a \"quoted\" string"

english
structural subtyping: ๊ตฌ์กฐ์  ์„œ๋ธŒํƒ€์ดํ•‘