<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
  <channel>
    <title>즐거운 하루 되시렵니까</title>
    <link>https://likelacoste.tistory.com/</link>
    <description></description>
    <language>ko</language>
    <pubDate>Thu, 9 Apr 2026 01:54:58 +0900</pubDate>
    <generator>TISTORY</generator>
    <ttl>100</ttl>
    <managingEditor>후끈후끈</managingEditor>
    <image>
      <title>즐거운 하루 되시렵니까</title>
      <url>https://tistory1.daumcdn.net/tistory/5352439/attach/de7cce7c3e5c40fea2177be9ceb8502b</url>
      <link>https://likelacoste.tistory.com</link>
    </image>
    <item>
      <title>TIL - Day3</title>
      <link>https://likelacoste.tistory.com/96</link>
      <description>&lt;h4 style=&quot;color: #000000;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;TIL(Today I Learned)&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;2024.01.07&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 style=&quot;color: #000000;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;오늘 읽은 범위&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;ep. 6~10&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 style=&quot;color: #000000;&quot; data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;책에서 기억하고 싶은 내용&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;ep.6&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;오류가 발생했을 때?&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;코드가 작동하지 않는 이유는 코드를 입력한 나 자신 때문이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;반드시 오류 메시지를 읽어라. 그리고 오류가 왜 발생했는지 원인을 찾고 이해해야한다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;ep.7&lt;/b&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;파이썬&lt;/b&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size14&quot;&gt;- 영어의 문법을 많이 따른다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size14&quot;&gt;- 다양한 곳에서 활용된다.(인공지능, 데이터, 웹 개발, 업무자동화, 게임 등)&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size14&quot;&gt;- 커뮤니티가 크다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size14&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;ep.8&lt;/b&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size14&quot;&gt;프로그래밍 언어는 크게 2가지 방법으로 번역되는데, 번역하는 방법에 따라 인터프리트 언어와 컴파일 언어로 나눠진다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size14&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;ep.10&lt;/b&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;코틀린&lt;/b&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size14&quot;&gt;- null에서 안전한 언어다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size14&quot;&gt;- 코루틴을 지원하는 언어다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size14&quot;&gt;- 안드로이드 앱 개발, React &amp;amp; Node.js(자바스크립트로 컴파일), 데이터 과학&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size14&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Books/IT 5분 잡학사전</category>
      <category>IT 5분 잡학사전</category>
      <category>개발자북클럽</category>
      <category>노개북</category>
      <category>노마드코더</category>
      <author>후끈후끈</author>
      <guid isPermaLink="true">https://likelacoste.tistory.com/96</guid>
      <comments>https://likelacoste.tistory.com/96#entry96comment</comments>
      <pubDate>Mon, 8 Jan 2024 00:39:38 +0900</pubDate>
    </item>
    <item>
      <title>TIL - Day2</title>
      <link>https://likelacoste.tistory.com/95</link>
      <description>&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;TIL(Today I Learned)&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;2024.01.06&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;오늘 읽은 범위&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;ep. 1 ~ 5&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;책에서 기억하고 싶은 내용&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;b&gt;ep.1&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;개발자?&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;- 논리적으로 생각하기를 좋아하고 문제 해결을 즐기는 사람&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;- 만들어 낸 결과물에서 청취감을 느끼는 사람&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;- 과정을 잘 이해할 수 있어야 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;- 끈기와 성실해야 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;- 포기하지 않고 끝까지 할 수 있어야 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;ep.2&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;어떤 언어를 선택해야 하는가?&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;정답은 없다. 내가 어떤 목적으로 프로그래밍을 하고 싶은지를 먼저 생각해보고 목적에 맞게 선택하면 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;ep.3&lt;/b&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;새로운 언어를 배울 때?&lt;/b&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size14&quot;&gt;먼저 공식문서를 살펴봐야 한다. 그리고 언어의 문법에 대해 보면서 직접 입력하고 이해해야 한다. 암기하고 이해하는 것에서 끝내는 것이 아니라 직접 코딩해보고 프로젝트를 만들어 봐야 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size14&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Books/IT 5분 잡학사전</category>
      <category>IT 5분 잡학사전</category>
      <category>개발자북클럽</category>
      <category>노개북</category>
      <category>노마드코더</category>
      <author>후끈후끈</author>
      <guid isPermaLink="true">https://likelacoste.tistory.com/95</guid>
      <comments>https://likelacoste.tistory.com/95#entry95comment</comments>
      <pubDate>Sat, 6 Jan 2024 13:39:05 +0900</pubDate>
    </item>
    <item>
      <title>[CSS] 미디어쿼리</title>
      <link>https://likelacoste.tistory.com/94</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;미디어 쿼리는 CSS에서 스타일을 선택적(단말기의 유형, 화면 해상도, 뷰포트 너비 등)으로 적용하고 싶을 때 사용합니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;미디어 쿼리 사용방법은 아래와 같이 사용할 수 있습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;- HTML link 태그 사용&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;html xml&quot; data-ke-language=&quot;html&quot;&gt;&lt;code&gt;&amp;lt;link rel=&quot;stylesheet&quot; type=&quot;text/css&quot; media=&quot;(조건)&quot; href=&quot;style.css&quot;&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;- CSS @media 키워드로 사용&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;css&quot; data-ke-language=&quot;css&quot;&gt;&lt;code&gt;@media all and (조건) and (조건) {}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;일반적으로는 CSS @media 키워드를 사용해서 스타일을 적용합니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;미디어 쿼리&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;code&gt;@media only all and (조건) and (조건) {}&lt;/code&gt;&lt;b&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&amp;nbsp;&lt;/h3&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;미디어 유형&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;미디어 유형은 장치의 일반적인 범주를 나타냅니다.&lt;/span&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;all&lt;/b&gt; : 모든 장치에 적합합니다.(기본값)&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;print&lt;/b&gt; : 인쇄 결과물 및 출력 미리보기 화면에 적용할 때사용합니다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;screen&lt;/b&gt; : 화면에 표시되는 부분에 적용할 때 사용합니다.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&amp;nbsp;&lt;/h3&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;논리 연산자&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;not, and, only 와 같은 논리 연산자를 사용하여 복잡한 쿼리를 조합할 수 있습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;and&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;다수의 미디어 특성을 조합하여 하나의 미디어 쿼리를 만들 때 사용합니다. 쿼리가 참이기 위해서는 모든 구성 특성이 참을 반환해야합니다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;미디어 쿼리의 조건은 모두 and 키워드로 연결합니다.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;not&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;미디어 쿼리를 부정하여, 쿼리가 거짓일 때만 참을 반환합니다. not 연산자를 사용할 경우 반드시 미디어 유형도 지정해야 합니다.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;only&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;전체 쿼리가 일치할 때만 스타일을 적용할 때 사용하며 오래 된 브라우저가 스타일을 잘못 적용하지 못하도록 방지합니다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;특정 미디어에만 적용하는 경우 사용됩니다.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&amp;nbsp;&lt;/h3&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;조건&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;반드시 괄호() 안에 조건을 입력해야 합니다.&lt;/span&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;min&lt;/b&gt; : 최소값이 일치할 때, 입력한 사이즈 &lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;이상&lt;/b&gt;&lt;/span&gt;부터 스타일이 적용됩니다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;max&lt;/b&gt; : 최대값이 일치할 때, 입력한 사이즈 &lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;이하&lt;/b&gt;&lt;/span&gt;부터 스타일이 적용됩니다.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;예시)&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;code&gt;@media only screen and (min-width: 320px){}&lt;/code&gt;&lt;/span&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;스크린 형태에만 적용&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;0 ~ 319px에서는 적용되지 않음&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;320px 부터 적용(확장 개념)&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;code&gt;@media only screen and (max-width: 320px){}&lt;/code&gt;&lt;/span&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;스크린 형태에만 적용&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;0 ~ 320px까지 적용됨(축소 개념)&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;321px 부터는 적용되지 않음&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;예시에서와 같이 미디어 쿼리를 적용하여 스타일을 적용하는 경우 아래와 같이 의문을 가질 수 있다.&lt;b&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;320px에는 과연 어떤 스타일이 적용될까?&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2023-09-20 16.52.55.png&quot; data-origin-width=&quot;996&quot; data-origin-height=&quot;444&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/X63wJ/btsuPQOj3aY/9bn3TGwqTmQkeO1kqKVsx1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/X63wJ/btsuPQOj3aY/9bn3TGwqTmQkeO1kqKVsx1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/X63wJ/btsuPQOj3aY/9bn3TGwqTmQkeO1kqKVsx1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FX63wJ%2FbtsuPQOj3aY%2F9bn3TGwqTmQkeO1kqKVsx1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;666&quot; height=&quot;297&quot; data-filename=&quot;스크린샷 2023-09-20 16.52.55.png&quot; data-origin-width=&quot;996&quot; data-origin-height=&quot;444&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;정답은 &lt;b&gt;&amp;lsquo;가장 마지막에 작성한 스타일이 적용된다&amp;rsquo;&lt;/b&gt; 입니다. 이러한 분기점을 &lt;b&gt;브레이크포인트(breakpoint)&lt;/b&gt;라고 합니다. 미디어쿼리르 적용할 때 분기점이 생기는 경우 어떤 스타일이 적용되는지를 미리 확인하고 적용해야 합니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;미디어 쿼리 분기&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;반응형으로 스타일을 적용할 때 일반적으로 아래와 같이 사이즈를 적용합니다.&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;arduino&quot;&gt;&lt;code&gt;/* 모바일 퍼스트*/

/* 모바일 */

@media (min-width: 768px){
    /* 태블릿 */
}

@media (min-width: 1024px){
    /* 랩탑, 데스크탑 */
}&lt;/code&gt;&lt;/pre&gt;
&lt;pre class=&quot;arduino&quot;&gt;&lt;code&gt;/* 테스크탑 퍼스트 */

/* 랩탑, 데스크탑 */

@media (max-width: 1023px){
    /* 태블릿 */
}

@media (max-width: 639px){
    /* 모바일 */
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;하지만 사이즈의 경우 절대적이지 않기 때문에 디자인에 맞게 적용하면 됩니다. 여기서 생각해봐야 하는 것은 모바일이나 태블릿의 경우 화면에 가로일 때와 세로일 때의 사이즈가 다르다는 점입니다. 그렇기 때문에 반응형으로 스타일을 적용하는 경우 디자인아니 기획자와의 회의를 통해 정한 다음 적용해야 합니다.&lt;/span&gt;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&amp;nbsp;&lt;/h3&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;미디어 쿼리 활용&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;code&gt;@media screen and (-webkit-max-device-pixel-ratio : 1){}&lt;/code&gt; : 고해상도 디스플레이가 아닌 경우&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;code&gt;@media screen and (orientation: portrait){}&lt;/code&gt; : 디바이스가 세로인 경우&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;code&gt;@media screen and (orientation: landscape){}&lt;/code&gt; : 디바이스가 가로인 경우&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;code&gt;@media (any-hover: none){}&lt;/code&gt; : 입력 방법이 hover를 지원하지 않는 경우(오직 터치스크린)&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>CSS</category>
      <category>@media</category>
      <category>미디어 쿼리</category>
      <category>반응형</category>
      <author>후끈후끈</author>
      <guid isPermaLink="true">https://likelacoste.tistory.com/94</guid>
      <comments>https://likelacoste.tistory.com/94#entry94comment</comments>
      <pubDate>Wed, 20 Sep 2023 17:12:12 +0900</pubDate>
    </item>
    <item>
      <title>[CSS] DPR(Device Pixel Ratio)</title>
      <link>https://likelacoste.tistory.com/93</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;해상도&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;해상도는 보통 1인치 안에 표현되는 화소(Pixel) 수를 의미합니다. 해상도가 높아지면 디스플레이의 화면은 선명해지는데, 이는 1인치 안에 픽셀의 수가 많아지기 때문입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;해당도의 밀도 단위, 즉 1인치당 가로, 세로를 이루는 픽셀의 수를 PPI(Pixel Per Inch)라고 합니다. PPI가 높아질 수록(밀도가 높아질 수록) 디스플레이의 화면은 선명해집니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;예를 들어 10 PPI는 정사각형 한 면(1inch)에 10개의 픽셀로, 총 100개의 픽셀로 이루어져있습니다. (10 X 10) 즉 10 PPI는 100개의 픽셀로, 20 PPI는 400개의 픽셀로 이루어져 있기 때문에 10 PPI 보다 20 PPI의 밀도가 더 높으며 높은 해상도를 보여준다는 것을 알 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;123.png&quot; data-origin-width=&quot;860&quot; data-origin-height=&quot;380&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/H6vA6/btsudX2gZFk/vgU6cghA8Jw5YrN4RLqLNk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/H6vA6/btsudX2gZFk/vgU6cghA8Jw5YrN4RLqLNk/img.png&quot; data-alt=&quot;출처 - https://mesign.tistory.com/9#google_vignette&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/H6vA6/btsudX2gZFk/vgU6cghA8Jw5YrN4RLqLNk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FH6vA6%2FbtsudX2gZFk%2FvgU6cghA8Jw5YrN4RLqLNk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;666&quot; height=&quot;294&quot; data-filename=&quot;123.png&quot; data-origin-width=&quot;860&quot; data-origin-height=&quot;380&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;출처 - https://mesign.tistory.com/9#google_vignette&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그리고 동일한 해상도를 가지고 있더라도 화면의 크기에 따라 PPI도 달라지기 때문에, 작은 화면일 수록 PPI가 높아 더 높은 밀도의 해상도를 가지고 있어 선명한 화면을 보여줍니다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&amp;nbsp;&lt;/h2&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;DPR(Device Pixel Ratio)&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;DPR은 디바이스의 물리적 픽셀(Physical Pixels)의 밀도와 논리적 픽셀(Logical Pixels)의 밀도 간의 비율을 말합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;물리적 픽셀(Physical Pixels)과 논리적 픽셀(Logical Pixels)이란?&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;물리적 픽셀(Physical Pixels)은 최종적으로 디바이스 화면에 출력되는 픽셀입니다. 즉 우리가 보는 디바이스의 실제 해상도를 이루는 픽셀이라고 할 수 있습니다.&lt;/li&gt;
&lt;li&gt;논리적 픽셀(Logical Pixels)은 css에서 표현하는 픽셀을 말합니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;일반적으로 웹 개발자는 정확한 배치를 위해 CSS의 픽셀을 측정하여 HTML과 CSS를 사용하여 페이지에 요소를 배치합니다. 그러나 사용되는 디바이스의 화면 크기의 종류는 너무나도 다양하기 때문에 CSS 픽셀로 지정한 것이 모든 디바이스의 화면에서 완벽하게 일치하지 않습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;우리가 보는 뷰포트(화면 영역의 크기)의 값은 css 픽셀 값이지만, 사용하는 디바이스의 화면은 물리적 픽셀이 단위입니다. 그리고 css 픽셀과 물리적 픽셀은 1:1 대응 관계가 아니기 때문에 디바이스 마다 서로 다른 DPR을 가지고 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;DPI = 물리적 픽셀(디바이스 픽셀) / 논리적 픽셀(cs&lt;b&gt;s 픽셀)&lt;/b&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2023-09-18 16.26.57.png&quot; data-origin-width=&quot;640&quot; data-origin-height=&quot;394&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bYHCa6/btsuGls8FAs/vi9AP4laPmrDzXPobRctPK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bYHCa6/btsuGls8FAs/vi9AP4laPmrDzXPobRctPK/img.png&quot; data-alt=&quot;출처 -&amp;amp;amp;nbsp;https://tomroth.com.au/dpr/&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bYHCa6/btsuGls8FAs/vi9AP4laPmrDzXPobRctPK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbYHCa6%2FbtsuGls8FAs%2Fvi9AP4laPmrDzXPobRctPK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;666&quot; height=&quot;410&quot; data-filename=&quot;스크린샷 2023-09-18 16.26.57.png&quot; data-origin-width=&quot;640&quot; data-origin-height=&quot;394&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;출처 -&amp;amp;nbsp;https://tomroth.com.au/dpr/&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;해상도가 높을 수록 높은 DPR을 가지고 있습니다. 이는 각 CSS 픽셀에 더 많은 화면 픽셀을 할당하기 때문에 더 선명하게 볼 수 있는 것입니다. 예를들어 DPR이 2라면, 1개의 CSS 픽셀을 4개의 물리적 픽셀이 표현하는 것이기 때문에 더 선명하게 보이는 것입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>CSS</category>
      <category>Device Pixel Ratio</category>
      <category>Logical Pixels</category>
      <category>Physical Pixels</category>
      <category>논리적 픽셀</category>
      <category>물리적 픽셀</category>
      <author>후끈후끈</author>
      <guid isPermaLink="true">https://likelacoste.tistory.com/93</guid>
      <comments>https://likelacoste.tistory.com/93#entry93comment</comments>
      <pubDate>Mon, 18 Sep 2023 16:23:38 +0900</pubDate>
    </item>
    <item>
      <title>[프로그래머스] 콜라 문제 - Javascript</title>
      <link>https://likelacoste.tistory.com/92</link>
      <description>&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;문제 출처&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/132267&quot;&gt;Lv.1 콜라 문제&lt;/a&gt;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&amp;nbsp;&lt;/h3&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;문제 설명&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;오래전 유행했던 콜라 문제가 있습니다. 콜라 문제의 지문은 다음과 같습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;정답은 아무에게도 말하지 마세요.&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #000000;&quot;&gt;콜라 빈 병 2개를 가져다주면 콜라 1병을 주는 마트가 있다. 빈 병 20개를 가져다주면 몇 병을 받을 수 있는가?&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #000000;&quot;&gt;단, 보유 중인 빈 병이 2개 미만이면, 콜라를 받을 수 없다.&lt;/span&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;문제를 풀던 상빈이는 콜라 문제의 완벽한 해답을 찾았습니다. 상빈이가 푼 방법은 아래 그림과 같습니다. 우선 콜라 빈 병 20병을 가져가서 10병을 받습니다. 받은 10병을 모두 마신 뒤, 가져가서 5병을 받습니다. 5병 중 4병을 모두 마신 뒤 가져가서 2병을 받고, 또 2병을 모두 마신 뒤 가져가서 1병을 받습니다. 받은 1병과 5병을 받았을 때 남은 1병을 모두 마신 뒤 가져가면 1병을 또 받을 수 있습니다. 이 경우 상빈이는 총 10 + 5 + 2 + 1 + 1 = 19병의 콜라를 받을 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;문제를 열심히 풀던 상빈이는 일반화된 콜라 문제를 생각했습니다. 이 문제는 빈 병 a개를 가져다주면 콜라 b병을 주는 마트가 있을 때, 빈 병 n개를 가져다주면 몇 병을 받을 수 있는지 계산하는 문제입니다. 기존 콜라 문제와 마찬가지로, 보유 중인 빈 병이 a개 미만이면, 추가적으로 빈 병을 받을 순 없습니다. 상빈이는 열심히 고심했지만, 일반화된 콜라 문제의 답을 찾을 수 없었습니다. 상빈이를 도와, 일반화된 콜라 문제를 해결하는 프로그램을 만들어 주세요.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;콜라를 받기 위해 마트에 주어야 하는 병 수 a, 빈 병 a개를 가져다 주면 마트가 주는 콜라 병 수 b, 상빈이가 가지고 있는 빈 병의 개수 n이 매개변수로 주어집니다. 상빈이가 받을 수 있는 콜라의 병 수를 return 하도록 solution 함수를 작성해주세요.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&amp;nbsp;&lt;/h3&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;제한 사항&lt;/b&gt;&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;1 &amp;le; b &amp;lt; a &amp;le; n &amp;le; 1,000,000&lt;/li&gt;
&lt;li&gt;정답은 항상 int 범위를 넘지 않게 주어집니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&amp;nbsp;&lt;/h3&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;&lt;b&gt;입출력 예&lt;/b&gt;&lt;/b&gt;&lt;/h3&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%; height: 51px;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 25%; height: 17px; text-align: center;&quot;&gt;&lt;b&gt;a&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 25%; height: 17px; text-align: center;&quot;&gt;&lt;b&gt;b&amp;nbsp;&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 25%; height: 17px; text-align: center;&quot;&gt;&lt;b&gt;n&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 25%; height: 17px; text-align: center;&quot;&gt;&lt;b&gt;result&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 25%; height: 17px; text-align: center;&quot;&gt;2&lt;/td&gt;
&lt;td style=&quot;width: 25%; height: 17px; text-align: center;&quot;&gt;1&lt;/td&gt;
&lt;td style=&quot;width: 25%; height: 17px; text-align: center;&quot;&gt;20&lt;/td&gt;
&lt;td style=&quot;width: 25%; height: 17px; text-align: center;&quot;&gt;19&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;width: 25%; height: 17px; text-align: center;&quot;&gt;3&lt;/td&gt;
&lt;td style=&quot;width: 25%; height: 17px; text-align: center;&quot;&gt;1&lt;/td&gt;
&lt;td style=&quot;width: 25%; height: 17px; text-align: center;&quot;&gt;20&lt;/td&gt;
&lt;td style=&quot;width: 25%; height: 17px; text-align: center;&quot;&gt;9&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;&lt;b&gt;입출력 예 설명&lt;/b&gt;&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;입출력 예 #1&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;본문에서 설명한 예시입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;&lt;b&gt;입출력 예 #2&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;빈 병 20개 중 18개를 마트에 가져가서, 6병의 콜라를 받습니다. 이때 상빈이가 가지고 있는 콜라 병의 수는 8(20 &amp;ndash; 18 + 6 = 8)개 입니다.&lt;/li&gt;
&lt;li&gt;빈 병 8개 중 6개를 마트에 가져가서, 2병의 콜라를 받습니다. 이때 상빈이가 가지고 있는 콜라 병의 수는 4(8 &amp;ndash; 6 + 2 = 4)개 입니다.&lt;/li&gt;
&lt;li&gt;빈 병 4 개중 3개를 마트에 가져가서, 1병의 콜라를 받습니다. 이때 상빈이가 가지고 있는 콜라 병의 수는 2(4 &amp;ndash; 3 + 1 = 2)개 입니다.&lt;/li&gt;
&lt;li&gt;3번의 교환 동안 상빈이는 9(6 + 2 + 1 = 9)병의 콜라를 받았습니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&amp;nbsp;&lt;/h3&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;풀이&lt;/b&gt;&lt;/h3&gt;
&lt;pre class=&quot;javascript&quot;&gt;&lt;code&gt;function solution(a, b, n) {
    let answer = 0 ;

    while(n &amp;gt;= a){
        let bringBotle = parseInt(n / a);
        let returnBotle = bringBotle * b;

        answer += returnBotle;
        n = returnBotle + (n % a);
    }
    return answer;
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>알고리즘/프로그래머스</category>
      <category>javascript</category>
      <category>알고리즘</category>
      <category>자바스크립트</category>
      <category>콜라 문제</category>
      <category>프로그래머스</category>
      <author>후끈후끈</author>
      <guid isPermaLink="true">https://likelacoste.tistory.com/92</guid>
      <comments>https://likelacoste.tistory.com/92#entry92comment</comments>
      <pubDate>Sat, 9 Sep 2023 00:05:57 +0900</pubDate>
    </item>
    <item>
      <title>Refresh token을 활용하여 Access token 갱신하기</title>
      <link>https://likelacoste.tistory.com/91</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;프로젝트를 진행하면서 access token이 만료되었을 때 refresh token을 사용하여 access token을 재발급 받아야 하는 상황이 생겼습니다. 그래서 token 재발급에 대해 생각해보고 방법에 대해 알아보겠습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;refresh token을 사용하여 만료된 access token을 갱신하는 방법&lt;/b&gt;&lt;/h2&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;클라이언트에서 API 요청을 보낸 후에 서버가 access 만료 여부를 확인합니다.&lt;/li&gt;
&lt;li&gt;만약 access token이 만료되었다면 401 response를 보내고, 응답받은 클라이언트는 이전에 발급받은 refresh token을 헤더에 담아 api 요청을 합니다.&lt;/li&gt;
&lt;li&gt;서버에서는 이전과 동일하게 refresh token 만료 여부를 확인합니다.&lt;/li&gt;
&lt;li&gt;만료가 되지 않은 경우에 access token을 재발급해서 클라이언트에게 전달하고 클라이언트는 발급받은 access token을 Header에 담아 이전에 보내던 API를 재 요청합니다.&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&amp;nbsp;&lt;/h2&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;axios interceptors&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;axios intercepter를 사용하면 then 또는 catch로 처리되기 전에 요청과 응답을 가로채어 추가적인 작업을 수행할 수 있습니다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;axios interceptors request&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;interceptors request는 api를 요청하기 전에 가로채어 작업할 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;클라이언트에서 JWT 토큰을 요청할 때 localStorage에서 access token을 가져와 Header의 Authorization에 담아서 보내는 경우 아래와 같이 코드를 작성할 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre class=&quot;routeros&quot;&gt;&lt;code&gt;axios.interceptors.request.use(
      async (config) =&amp;gt; {
        if (config.url === tokenUrl) {
          config.headers.Authorization = null;
          config.headers.Authorization = `Bearer ${localStorage.getItem(
            &quot;refresh&quot;
          )}`;
        } else {
          config.headers.Authorization = !!localStorage.getItem(&quot;access&quot;)
            ? `Bearer ${localStorage.getItem(&quot;access&quot;)}`
            : null;
        }
        return config;
      },
      (error) =&amp;gt; {
        return Promise.reject(error);
      }
    );&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Token을 재발급 받는 경우가 아닐 때는 access token을 Authorization에 담아야 하므로 해당 조건을 분기해주어 상황에 맞는 token을 localStorage에서 가져와 Bearer 형식으로 config에 저장해주면 됩니다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&amp;nbsp;&lt;/h3&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;axios interceptors response&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;interceptors response는 API를 요청한 후에 응답을 가로채어 작업할 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;token이 만료되어 서버로부터 401 에러를 받았을 때 token 재발급 요청을 보낸 뒤에 이전에 보냈던 요청을 재요청하는 코드를 아래와 같이 작성할 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre class=&quot;javascript&quot;&gt;&lt;code&gt;axios.interceptors.response.use(
      (response) =&amp;gt; {
        return response;
      },
      async (error) =&amp;gt; {
        const {
          config: originalRequest,
          response,
        } = error;

        if (response.status === 401 &amp;amp;&amp;amp; !originalRequest.sent) {
          originalRequest.sent = true;
          try {
            const response = await axios.get(tokenUrl);
            if (response) {
              const { accessToken, refreshToken } = response.data;
              originalRequest.headers.Authorization = `Bearer ${accessToken}`;

              localStorage.setItem(accessToken, &quot;access&quot;);
              localStorage.setItem(refreshToken, &quot;refresh&quot;);
            }
          } catch (_error) {
            const {
              response: { data },
            } = _error;

            if (data.code === 403) {
              localStorage.removeItem(&quot;access&quot;);
              localStorage.removeItem(&quot;refresh&quot;);
              window.location.href = &quot;/&quot;;
            }
          }
          return axios(originalRequest);
        }
        return Promise.reject(error);
      }
    );
  }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;response callback 함수의 첫번째 인자에는 정상적인 응답을, 두 번째 인자에는 에러 응답을 전달받게 됩니다. access token이 만료되었을 때 에러 응답을 받기 때문에 두 번째 인자에서만 callback 함수를 정의하였습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;refresh 요청이 끝나고 재요청을 보냈을 때 에러가 발생한 경우 재귀적으로 loop가 발생할 수 있기 때문에 이를 방지하기 위한 config.sent를 true로 설정해주고 조건문에 함께 추가해주었습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;refresh 요청 중에 refresh token이 만료된 경우에는 localStorage에 저장되어 있는 token 정보를 삭제한 후에 홈으로 이동시켰습니다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&amp;nbsp;&lt;/h2&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;마치며&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;JWT는 확장성이 높은 인가 처리 방식이면서 refresh token을 활용하여 보안을 보다 강화할 수 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다만 access, refresh token을 어디에 저장하고 어떻게 전달하면서 갱신하고, 다양한 기기에서 다중 로그인을 지원하기 위해 여러개를 어떻게 다룰 것인지에 따라 구현 난이도가 올라가며, 최상의 방법에 대한 문서를 찾는것도 쉽지 않습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;작성된 코드를 보면서 불필요한 부분이 무엇인지, 조금 더 개선할 부분이 무엇이 있는지 계속해서 업데이트해봐야 할 것 같습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>개발이야기</category>
      <category>access token</category>
      <category>axios</category>
      <category>axios interceptors</category>
      <category>axios interceptors request</category>
      <category>axios interceptors response</category>
      <category>refresh token</category>
      <category>토큰 재발급</category>
      <author>후끈후끈</author>
      <guid isPermaLink="true">https://likelacoste.tistory.com/91</guid>
      <comments>https://likelacoste.tistory.com/91#entry91comment</comments>
      <pubDate>Tue, 5 Sep 2023 17:51:23 +0900</pubDate>
    </item>
    <item>
      <title>[프로그래머스] 개인정보 수집 유효기간 - Javascript</title>
      <link>https://likelacoste.tistory.com/90</link>
      <description>&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;문제 출처&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;a href=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/150370&quot;&gt;Lv.1 개인정보 수집 유효기간&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&amp;nbsp;&lt;/h3&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;문제 설명&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;고객의 약관 동의를 얻어서 수집된 1~n번으로 분류되는 개인정보 n개가 있습니다. 약관 종류는 여러 가지 있으며 각 약관마다 개인정보 보관 유효기간이 정해져 있습니다. 당신은 각 개인정보가 어떤 약관으로 수집됐는지 알고 있습니다. 수집된 개인정보는 유효기간 전까지만 보관 가능하며, 유효기간이 지났다면 반드시 파기해야 합니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;예를 들어, A라는 약관의 유효기간이 12 달이고, 2021년 1월 5일에 수집된 개인정보가 A약관으로 수집되었다면 해당 개인정보는 2022년 1월 4일까지 보관 가능하며 2022년 1월 5일부터 파기해야 할 개인정보입니다.&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;당신은 오늘 날짜로 파기해야 할 개인정보 번호들을 구하려 합니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;모든 달은 28일까지 있다고 가정합니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;오늘 날짜를 의미하는 문자열 today, 약관의 유효기간을 담은 1차원 문자열 배열 terms와 수집된 개인정보의 정보를 담은 1차원 문자열 배열 privacies가 매개변수로 주어집니다. 이때 파기해야 할 개인정보의 번호를 오름차순으로 1차원 정수 배열에 담아 return 하도록 solution 함수를 완성해 주세요.&lt;/span&gt;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&amp;nbsp;&lt;/h3&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;제한 사항&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;today는 &quot;YYYY.MM.DD&quot; 형태로 오늘 날짜를 나타냅니다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;1 &amp;le; terms의 길이 &amp;le; 20&lt;/span&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;terms의 원소는 &quot;약관 종류 유효기간&quot; 형태의 약관 종류와 유효기간을 공백 하나로 구분한 문자열입니다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;약관 종류는 A~Z중 알파벳 대문자 하나이며, terms 배열에서 약관 종류는 중복되지 않습니다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;유효기간은 개인정보를 보관할 수 있는 달 수를 나타내는 정수이며, 1 이상 100 이하입니다.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;1 &amp;le; privacies의 길이 &amp;le; 100&lt;/span&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;privacies[i]는 i+1번 개인정보의 수집 일자와 약관 종류를 나타냅니다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;privacies의 원소는 &quot;날짜 약관 종류&quot; 형태의 날짜와 약관 종류를 공백 하나로 구분한 문자열입니다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;날짜는 &quot;YYYY.MM.DD&quot; 형태의 개인정보가 수집된 날짜를 나타내며, today 이전의 날짜만 주어집니다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;privacies의 약관 종류는 항상 terms에 나타난 약관 종류만 주어집니다.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;today와 privacies에 등장하는 날짜의 YYYY는 연도, MM은 월, DD는 일을 나타내며 점(.) 하나로 구분되어 있습니다.&lt;/span&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;2000 &amp;le; YYYY &amp;le; 2022&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;1 &amp;le; MM &amp;le; 12&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;MM이 한 자릿수인 경우 앞에 0이 붙습니다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;1 &amp;le; DD &amp;le; 28&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;DD가 한 자릿수인 경우 앞에 0이 붙습니다.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;파기해야 할 개인정보가 하나 이상 존재하는 입력만 주어집니다.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&amp;nbsp;&lt;/h3&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;&lt;b&gt;입출력 예&lt;/b&gt;&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;table style=&quot;height: 90px;&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;thead&gt;
&lt;tr style=&quot;height: 18px;&quot;&gt;
&lt;th style=&quot;height: 18px;&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;today&lt;/b&gt;&lt;/span&gt;&lt;/th&gt;
&lt;th style=&quot;height: 18px;&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;terms&lt;/b&gt;&lt;/span&gt;&lt;/th&gt;
&lt;th style=&quot;height: 18px;&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;privacles&lt;/b&gt;&lt;/span&gt;&lt;/th&gt;
&lt;th style=&quot;height: 18px;&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;result&lt;/b&gt;&lt;/span&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr style=&quot;height: 36px;&quot;&gt;
&lt;td style=&quot;height: 36px;&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&quot;2022.05.19&quot;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;height: 36px;&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;[&quot;A 6&quot;, &quot;B 12&quot;, &quot;C 3&quot;]&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;height: 36px;&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;[&quot;2021.05.02 A&quot;, &quot;2021.07.01 B&quot;, &quot;2022.02.19 C&quot;, &quot;2022.02.20 C&quot;]&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;height: 36px;&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;[1, 3]&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 36px;&quot;&gt;
&lt;td style=&quot;height: 36px;&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&quot;2020.01.01&quot;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;height: 36px;&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;[&quot;Z 3&quot;, &quot;D 5&quot;]&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;height: 36px;&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;[&quot;2019.01.01 D&quot;, &quot;2019.11.15 Z&quot;, &quot;2019.08.02 D&quot;, &quot;2019.07.01 D&quot;, &quot;2018.12.28 Z&quot;]&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;height: 36px;&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;[1, 4, 5]&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&amp;nbsp;&lt;/h3&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;풀이&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;pre class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot;&gt;&lt;code&gt;function solution(today, terms, privacies) {
    const answer = [];
    const toDay = new Date(today);
    const termMap = new Map();

    terms.forEach((term)=&amp;gt;{
        const [type, termMonth] = term.split(' ');
        termMap.set(type, Number(termMonth));
    })

    privacies.forEach((pri, index) =&amp;gt; {
        const [date, type] = pri.split(' ');
        const privacyDate = new Date(date);

        privacyDate.setMonth(privacyDate.getMonth() + termMap.get(type));

        if(privacyDate &amp;lt;= toDay) answer.push(index + 1);
    })
    return answer;
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;new Date() 메서드를 사용해서 풀수 있는 문제이다. 모든 달은 28일까지 있다고 가정하기 때문에 날짜는 상관하지 않고 달 기준으로 계산하면 된다.&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>알고리즘/프로그래머스</category>
      <category>javascript</category>
      <category>개인정보 수집 유효기간</category>
      <category>알고리즘</category>
      <category>프로그래머스</category>
      <author>후끈후끈</author>
      <guid isPermaLink="true">https://likelacoste.tistory.com/90</guid>
      <comments>https://likelacoste.tistory.com/90#entry90comment</comments>
      <pubDate>Mon, 4 Sep 2023 22:58:19 +0900</pubDate>
    </item>
    <item>
      <title>[프로그래머스] 크기가 작은 부분문자열 - Javascript</title>
      <link>https://likelacoste.tistory.com/89</link>
      <description>&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;문제 출처&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/147355&quot;&gt;Lv.1 크기가 작은 부분문자열&lt;/a&gt;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&amp;nbsp;&lt;/h3&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;문제 설명&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;숫자로 이루어진 문자열 t와 p가 주어질 때, t에서 p와 길이가 같은 부분문자열 중에서, 이 부분문자열이 나타내는 수가 p가 나타내는 수보다 작거나 같은 것이 나오는 횟수를 return하는 함수 solution을 완성하세요.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;예를 들어, t=&quot;3141592&quot;이고 p=&quot;271&quot; 인 경우, t의 길이가 3인 부분 문자열은 314, 141, 415, 159, 592입니다. 이 문자열이 나타내는 수 중 271보다 작거나 같은 수는 141, 159 2개 입니다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&amp;nbsp;&lt;/h3&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;제한 사항&lt;/b&gt;&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;1 &amp;le; p의 길이 &amp;le; 18&lt;/li&gt;
&lt;li&gt;p의 길이 &amp;le; t의 길이 &amp;le; 10,000&lt;/li&gt;
&lt;li&gt;t와 p는 숫자로만 이루어진 문자열이며, 0으로 시작하지 않습니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&amp;nbsp;&lt;/h3&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;&lt;b&gt;입출력 예&lt;/b&gt;&lt;/b&gt;&lt;/h3&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 33.3333%; text-align: center;&quot;&gt;&lt;b&gt;t&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; text-align: center;&quot;&gt;&lt;b&gt;p&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; text-align: center;&quot;&gt;&lt;b&gt;result&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 33.3333%; text-align: center;&quot;&gt;&quot;3141592&quot;&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; text-align: center;&quot;&gt;&quot;271&quot;&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; text-align: center;&quot;&gt;2&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 33.3333%; text-align: center;&quot;&gt;&quot;500220839878&quot;&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; text-align: center;&quot;&gt;&quot;7&quot;&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; text-align: center;&quot;&gt;8&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 33.3333%; text-align: center;&quot;&gt;&quot;10203&quot;&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; text-align: center;&quot;&gt;&quot;15&quot;&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; text-align: center;&quot;&gt;3&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&amp;nbsp;&lt;/h3&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;&lt;b&gt;입출력 예 설명&lt;/b&gt;&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;입출력 예 #1&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;본문과 같습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;입출력 예 #2&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;p의 길이가 1이므로 t의 부분문자열은 &quot;5&quot;, &quot;0&quot;, 0&quot;, &quot;2&quot;, &quot;2&quot;, &quot;0&quot;, &quot;8&quot;, &quot;3&quot;, &quot;9&quot;, &quot;8&quot;, &quot;7&quot;, &quot;8&quot;이며 이중 7보다 작거나 같은 숫자는 &quot;5&quot;, &quot;0&quot;, &quot;0&quot;, &quot;2&quot;, &quot;2&quot;, &quot;0&quot;, &quot;3&quot;, &quot;7&quot; 이렇게 8개가 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;입출력 예 #3&lt;/b&gt;&lt;br /&gt;p의 길이가 2이므로 t의 부분문자열은 &quot;10&quot;, &quot;02&quot;, &quot;20&quot;, &quot;03&quot;이며, 이중 15보다 작거나 같은 숫자는 &quot;10&quot;, &quot;02&quot;, &quot;03&quot; 이렇게 3개입니다. &quot;02&quot;와 &quot;03&quot;은 각각 2, 3에 해당한다는 점에 주의하세요&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&amp;nbsp;&lt;/h3&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;풀이&lt;/b&gt;&lt;/h3&gt;
&lt;pre class=&quot;matlab&quot;&gt;&lt;code&gt;function solution(t, p) {
    let answer = 0;

    for(let i=0; i&amp;lt;=(t.length-p.length); i++){
        let newNum =t.split('').slice(i,i+(p.length)).join('');
        if(Number(newNum) &amp;lt;= Number(p)){
            answer++;
        }
    }
    return answer;
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>알고리즘/프로그래머스</category>
      <category>javascript</category>
      <category>알고리즘</category>
      <category>자바스크립트</category>
      <category>크기가 작은 부분문자열</category>
      <category>프로그래머스</category>
      <author>후끈후끈</author>
      <guid isPermaLink="true">https://likelacoste.tistory.com/89</guid>
      <comments>https://likelacoste.tistory.com/89#entry89comment</comments>
      <pubDate>Sun, 3 Sep 2023 20:00:26 +0900</pubDate>
    </item>
    <item>
      <title>[프로그래머스] 카드 뭉치 - Javascript</title>
      <link>https://likelacoste.tistory.com/88</link>
      <description>&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;문제 출처&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/159994&quot;&gt;Lv.1 카드 뭉치&lt;/a&gt;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&amp;nbsp;&lt;/h3&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;문제 설명&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;코니는 영어 단어가 적힌 카드 뭉치 두 개를 선물로 받았습니다. 코니는 다음과 같은 규칙으로 카드에 적힌 단어들을 사용해 원하는 순서의 단어 배열을 만들 수 있는지 알고 싶습니다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;원하는 카드 뭉치에서 카드를 순서대로 한 장씩 사용합니다.&lt;/li&gt;
&lt;li&gt;한 번 사용한 카드는 다시 사용할 수 없습니다.&lt;/li&gt;
&lt;li&gt;카드를 사용하지 않고 다음 카드로 넘어갈 수 없습니다.&lt;/li&gt;
&lt;li&gt;기존에 주어진 카드 뭉치의 단어 순서는 바꿀 수 없습니다.&lt;br /&gt;예를 들어 첫 번째 카드 뭉치에 순서대로 [&quot;i&quot;, &quot;drink&quot;, &quot;water&quot;], 두 번째 카드 뭉치에 순서대로 [&quot;want&quot;, &quot;to&quot;]가 적혀있을 때 [&quot;i&quot;, &quot;want&quot;, &quot;to&quot;, &quot;drink&quot;, &quot;water&quot;] 순서의 단어 배열을 만들려고 한다면 첫 번째 카드 뭉치에서 &quot;i&quot;를 사용한 후 두 번째 카드 뭉치에서 &quot;want&quot;와 &quot;to&quot;를 사용하고 첫 번째 카드뭉치에 &quot;drink&quot;와 &quot;water&quot;를 차례대로 사용하면 원하는 순서의 단어 배열을 만들 수 있습니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;문자열로 이루어진 배열 cards1, cards2와 원하는 단어 배열 goal이 매개변수로 주어질 때, cards1과 cards2에 적힌 단어들로 goal를 만들 있다면 &quot;Yes&quot;를, 만들 수 없다면 &quot;No&quot;를 return하는 solution 함수를 완성해주세요.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;제한 사항&lt;/b&gt;&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;1 &amp;le; cards1의 길이, cards2의 길이 &amp;le; 10
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;1 &amp;le; cards1[i]의 길이, cards2[i]의 길이 &amp;le; 10&lt;/li&gt;
&lt;li&gt;cards1과 cards2에는 서로 다른 단어만 존재합니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;2 &amp;le; goal의 길이 &amp;le; cards1의 길이 + cards2의 길이
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;1 &amp;le; goal[i]의 길이 &amp;le; 10&lt;/li&gt;
&lt;li&gt;goal의 원소는 cards1과 cards2의 원소들로만 이루어져 있습니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;cards1, cards2, goal의 문자열들은 모두 알파벳 소문자로만 이루어져 있습니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&amp;nbsp;&lt;/h3&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;&lt;b&gt;입출력 예&lt;/b&gt;&lt;/b&gt;&lt;/h3&gt;
&lt;table style=&quot;height: 53px; width: 825px;&quot; width=&quot;835&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;thead&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;th style=&quot;height: 17px; width: 247px;&quot;&gt;&lt;b&gt;cards1&lt;/b&gt;&lt;/th&gt;
&lt;th style=&quot;height: 17px; width: 169px;&quot;&gt;&lt;b&gt;cards2&lt;/b&gt;&lt;/th&gt;
&lt;th style=&quot;height: 17px; width: 342px;&quot;&gt;goal&lt;/th&gt;
&lt;th style=&quot;width: 67px; height: 17px;&quot;&gt;&lt;b&gt;&lt;b&gt;result&lt;/b&gt;&lt;/b&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr style=&quot;height: 18px;&quot;&gt;
&lt;td style=&quot;text-align: center; height: 18px; width: 247px;&quot;&gt;[&quot;i&quot;,&amp;nbsp;&quot;drink&quot;,&amp;nbsp;&quot;water&quot;]&lt;/td&gt;
&lt;td style=&quot;text-align: center; height: 18px; width: 169px;&quot;&gt;[&quot;want&quot;,&amp;nbsp;&quot;to&quot;]&lt;/td&gt;
&lt;td style=&quot;text-align: center; height: 18px; width: 342px;&quot;&gt;[&quot;i&quot;,&amp;nbsp;&quot;want&quot;,&amp;nbsp;&quot;to&quot;,&amp;nbsp;&quot;drink&quot;,&amp;nbsp;&quot;water&quot;]&lt;/td&gt;
&lt;td style=&quot;text-align: center; width: 67px; height: 18px;&quot;&gt;'Yes'&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 18px;&quot;&gt;
&lt;td style=&quot;text-align: center; height: 18px; width: 247px;&quot;&gt;[&quot;i&quot;,&amp;nbsp;&quot;water&quot;,&amp;nbsp;&quot;drink&quot;]&lt;/td&gt;
&lt;td style=&quot;text-align: center; height: 18px; width: 169px;&quot;&gt;[&quot;want&quot;,&amp;nbsp;&quot;to&quot;]&lt;/td&gt;
&lt;td style=&quot;text-align: center; height: 18px; width: 342px;&quot;&gt;[-1]&lt;/td&gt;
&lt;td style=&quot;text-align: center; width: 67px; height: 18px;&quot;&gt;'No'&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&amp;nbsp;&lt;/h3&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;&lt;b&gt;입출력 예 설명&lt;/b&gt;&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;입출력 예 #1&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;본문과 같습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;입출력 예 #2&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;cards1에서 &quot;i&quot;를 사용하고 cards2에서 &quot;want&quot;와 &quot;to&quot;를 사용하여 &quot;i want to&quot;까지는 만들 수 있지만 &quot;water&quot;가 &quot;drink&quot;보다 먼저 사용되어야 하기 때문에 해당 문장을 완성시킬 수 없습니다. 따라서 &quot;No&quot;를 반환합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;풀이&lt;/b&gt;&lt;/h3&gt;
&lt;pre class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot;&gt;&lt;code&gt;function solution(cards1, cards2, goal) {
    let answer = 'Yes'
    
    goal.forEach((card) =&amp;gt; {
        if(cards1[0] === card) cards1.shift();
        else if(cards2[0] === card) cards2.shift();
        else if(cards1[0] !== card &amp;amp;&amp;amp; cards2[0] !== card){
            answer = 'No';
            return;
        }
    })
    
    return answer;
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;goal 배열을 순회하면서 cards1와 cards2의 가장 첫 번째 요소가 순회 중인 카드인지 여부를 확인한다. cards1의 가장 앞 요소가 확인 중인 카드와 동일한 경우에는 cards1의 가장 앞 요소를, cards2의 가장 앞 요소가 확인 중인 카드와 동일한 경우 cards2의 가장 앞 요소를 제거해준다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;만약 둘 다 해당 되지 않는 경우에는 카드의 순서를 변경할 수 없기 때문에 만들 수 없다고 판단하고 answer 변수에 'No'를 할당해 준 후에 반복문을 종료하고 값을 반환해준다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>알고리즘/프로그래머스</category>
      <category>javascript</category>
      <category>알고리즘</category>
      <category>카드 뭉치</category>
      <category>프로그래머스</category>
      <author>후끈후끈</author>
      <guid isPermaLink="true">https://likelacoste.tistory.com/88</guid>
      <comments>https://likelacoste.tistory.com/88#entry88comment</comments>
      <pubDate>Thu, 31 Aug 2023 23:41:50 +0900</pubDate>
    </item>
    <item>
      <title>[프로그래머스] 대충 만든 자판 - Javascript</title>
      <link>https://likelacoste.tistory.com/87</link>
      <description>&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;문제 출처&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/160586&quot;&gt;Lv.1 대충 만든 자판&lt;/a&gt;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&amp;nbsp;&lt;/h3&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;문제 설명&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;휴대폰의 자판은 컴퓨터 키보드 자판과는 다르게 하나의 키에 여러 개의 문자가 할당될 수 있습니다. 키 하나에 여러 문자가 할당된 경우, 동일한 키를 연속해서 빠르게 누르면 할당된 순서대로 문자가 바뀝니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;예를 들어, 1번 키에 &quot;A&quot;, &quot;B&quot;, &quot;C&quot; 순서대로 문자가 할당되어 있다면 1번 키를 한 번 누르면 &quot;A&quot;, 두 번 누르면 &quot;B&quot;, 세 번 누르면 &quot;C&quot;가 되는 식입니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;같은 규칙을 적용해 아무렇게나 만든 휴대폰 자판이 있습니다. 이 휴대폰 자판은 키의 개수가 1개부터 최대 100개까지 있을 수 있으며, 특정 키를 눌렀을 때 입력되는 문자들도 무작위로 배열되어 있습니다. 또, 같은 문자가 자판 전체에 여러 번 할당된 경우도 있고, 키 하나에 같은 문자가 여러 번 할당된 경우도 있습니다. 심지어 아예 할당되지 않은 경우도 있습니다. 따라서 몇몇 문자열은 작성할 수 없을 수도 있습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 휴대폰 자판을 이용해 특정 문자열을 작성할 때, 키를 최소 몇 번 눌러야 그 문자열을 작성할 수 있는지 알아보고자 합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1번 키부터 차례대로 할당된 문자들이 순서대로 담긴 문자열배열 keymap과 입력하려는 문자열들이 담긴 문자열 배열 targets가 주어질 때, 각 문자열을 작성하기 위해 키를 최소 몇 번씩 눌러야 하는지 순서대로 배열에 담아 return 하는 solution 함수를 완성해 주세요.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;단, 목표 문자열을 작성할 수 없을 때는 -1을 저장합니다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&amp;nbsp;&lt;/h3&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;제한 사항&lt;/b&gt;&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;1 &amp;le; keymap의 길이 &amp;le; 100
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;1 &amp;le; keymap의 원소의 길이 &amp;le; 100&lt;/li&gt;
&lt;li&gt;keymap[i]는 i + 1번 키를 눌렀을 때 순서대로 바뀌는 문자를 의미합니다.
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;예를 들어 keymap[0] = &quot;ABACD&quot; 인 경우 1번 키를 한 번 누르면 A, 두 번 누르면 B, 세 번 누르면 A 가 됩니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;keymap의 원소의 길이는 서로 다를 수 있습니다.&lt;/li&gt;
&lt;li&gt;keymap의 원소는 알파벳 대문자로만 이루어져 있습니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;1 &amp;le; targets의 길이 &amp;le; 100
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;1 &amp;le; targets의 원소의 길이 &amp;le; 100&lt;/li&gt;
&lt;li&gt;targets의 원소는 알파벳 대문자로만 이루어져 있습니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&amp;nbsp;&lt;/h3&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;&lt;b&gt;입출력 예&lt;/b&gt;&lt;/b&gt;&lt;/h3&gt;
&lt;table style=&quot;height: 72px;&quot; width=&quot;882&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;thead&gt;
&lt;tr style=&quot;height: 18px;&quot;&gt;
&lt;th style=&quot;height: 18px;&quot;&gt;&lt;b&gt;keymap&lt;/b&gt;&lt;/th&gt;
&lt;th style=&quot;height: 18px;&quot;&gt;&lt;b&gt;targets&lt;/b&gt;&lt;/th&gt;
&lt;th style=&quot;height: 18px;&quot;&gt;&lt;b&gt;result&lt;/b&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr style=&quot;height: 18px;&quot;&gt;
&lt;td style=&quot;height: 18px; text-align: center;&quot;&gt;[&quot;ABACD&quot;, &quot;BCEFD&quot;]&lt;/td&gt;
&lt;td style=&quot;height: 18px; text-align: center;&quot;&gt;[&quot;ABCD&quot;,&quot;AABB&quot;]&lt;/td&gt;
&lt;td style=&quot;height: 18px; text-align: center;&quot;&gt;[9, 4]&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 18px;&quot;&gt;
&lt;td style=&quot;height: 18px; text-align: center;&quot;&gt;[&quot;AA&quot;]&lt;/td&gt;
&lt;td style=&quot;height: 18px; text-align: center;&quot;&gt;[&quot;B&quot;]&lt;/td&gt;
&lt;td style=&quot;height: 18px; text-align: center;&quot;&gt;[-1]&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 18px;&quot;&gt;
&lt;td style=&quot;height: 18px; text-align: center;&quot;&gt;[&quot;AGZ&quot;, &quot;BSSS&quot;]&lt;/td&gt;
&lt;td style=&quot;height: 18px; text-align: center;&quot;&gt;[&quot;ASA&quot;,&quot;BGZ&quot;]&lt;/td&gt;
&lt;td style=&quot;height: 18px; text-align: center;&quot;&gt;[4, 6]&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&amp;nbsp;&lt;/h3&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;&lt;b&gt;입출력 예 설명&lt;/b&gt;&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;입출력 예 #1&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&quot;ABCD&quot;의 경우,&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;1번 키 한 번 &amp;rarr; A&lt;/li&gt;
&lt;li&gt;2번 키 한 번 &amp;rarr; B&lt;/li&gt;
&lt;li&gt;2번 키 두 번 &amp;rarr; C&lt;/li&gt;
&lt;li&gt;1번 키 다섯 번 &amp;rarr; D&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;따라서 총합인 9를 첫 번째 인덱스에 저장합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&quot;AABB&quot;의 경우,&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;1번 키 한 번 &amp;rarr; A&lt;/li&gt;
&lt;li&gt;1번 키 한 번 &amp;rarr; A&lt;/li&gt;
&lt;li&gt;2번 키 한 번 &amp;rarr; B&lt;/li&gt;
&lt;li&gt;2번 키 한 번 &amp;rarr; B&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;따라서 총합인 4를 두 번째 인덱스에 저장합니다.&lt;br /&gt;결과적으로 [9,4]를 return 합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;&lt;b&gt;입출력 예 #2&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&quot;B&quot;의 경우, 'B'가 어디에도 존재하지 않기 때문에 -1을 첫 번째 인덱스에 저장합니다.&lt;br /&gt;결과적으로 [-1]을 return 합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;&lt;b&gt;입출력 예 #3&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&quot;ASA&quot;의 경우,&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;1번 키 한 번 &amp;rarr; A&lt;/li&gt;
&lt;li&gt;2번 키 두 번 &amp;rarr; S&lt;/li&gt;
&lt;li&gt;1번 키 한 번 &amp;rarr; A&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;따라서 총합인 4를 첫 번째 인덱스에 저장합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;&quot;BGZ&quot;의 경우,&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;2번 키 한 번 &amp;rarr; B&lt;/li&gt;
&lt;li&gt;1번 키 두 번 &amp;rarr; G&lt;/li&gt;
&lt;li&gt;1번 키 세 번 &amp;rarr; Z&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;따라서 총합인 6을 두 번째 인덱스에 저장합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;결과적으로 [4, 6]을 return 합니다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&amp;nbsp;&lt;/h3&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;풀이&lt;/b&gt;&lt;/h3&gt;
&lt;pre class=&quot;javascript&quot;&gt;&lt;code&gt;function solution(keymap, targets) {
    const answer = [];
    const map = new Map();

    keymap.forEach((keys) =&amp;gt; {
        const targetArr = [...keys];
        targetArr.forEach((key, idx) =&amp;gt; {
            if(!map.has(key) || idx + 1 &amp;lt; map.get(key)){
                map.set(key, idx + 1);
            }
        })
    })

    targets.forEach((target) =&amp;gt; {
        const targetArr = [...target];
        let count = 0;

        targetArr.forEach((targetKey) =&amp;gt; {
            count += map.get(targetKey)
        })

        answer.push(count || -1);
    })

    return answer;
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;문자를 최소 횟수로 출력하기 위해 Map 객체를 사용하였다.&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;keymap을 순회하면서 map 객체에 key가 없거나 또는 key를 호출하기 위해 누른 횟수가 map 객체 key의 값보다 작은 경우 해당 key의 value로 저장한다.&lt;/li&gt;
&lt;li&gt;targets를 순회하면서 map 객체에서 key에 대한 값을 가져와서 count에 더한다.&lt;/li&gt;
&lt;li&gt;count의 값이 없는 경우에는 -1를, 있는 경우에는 count를 answer 배열에 push 한다.&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>알고리즘/프로그래머스</category>
      <category>javascript</category>
      <category>대충 만든 자판</category>
      <category>알고리즘</category>
      <category>코딩테스트</category>
      <category>프로그래머스</category>
      <author>후끈후끈</author>
      <guid isPermaLink="true">https://likelacoste.tistory.com/87</guid>
      <comments>https://likelacoste.tistory.com/87#entry87comment</comments>
      <pubDate>Wed, 30 Aug 2023 17:42:43 +0900</pubDate>
    </item>
    <item>
      <title>[프로그래머스] 덧칠하기 - Javascript</title>
      <link>https://likelacoste.tistory.com/86</link>
      <description>&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;문제 출처&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/161989&quot;&gt;Lv.1 덧칠하기&lt;/a&gt;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&amp;nbsp;&lt;/h3&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;문제 설명&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;어느 학교에 페인트가 칠해진 길이가 n미터인 벽이 있습니다. 벽에 동아리 &amp;middot; 학회 홍보나 회사 채용 공고 포스터 등을 게시하기 위해 테이프로 붙였다가 철거할 때 떼는 일이 많고 그 과정에서 페인트가 벗겨지곤 합니다. 페인트가 벗겨진 벽이 보기 흉해져 학교는 벽에 페인트를 덧칠하기로 했습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;넓은 벽 전체에 페인트를 새로 칠하는 대신, 구역을 나누어 일부만 페인트를 새로 칠 함으로써 예산을 아끼려 합니다. 이를 위해 벽을 1미터 길이의 구역 n개로 나누고, 각 구역에 왼쪽부터 순서대로 1번부터 n번까지 번호를 붙였습니다. 그리고 페인트를 다시 칠해야 할 구역들을 정했습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;벽에 페인트를 칠하는 롤러의 길이는 m미터이고, 롤러로 벽에 페인트를 한 번 칠하는 규칙은 다음과 같습니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;롤러가 벽에서 벗어나면 안 됩니다.&lt;br /&gt;구역의 일부분만 포함되도록 칠하면 안 됩니다.&lt;br /&gt;즉, 롤러의 좌우측 끝을 구역의 경계선 혹은 벽의 좌우측 끝부분에 맞춘 후 롤러를 위아래로 움직이면서 벽을 칠합니다. 현재 페인트를 칠하는 구역들을 완전히 칠한 후 벽에서 롤러를 떼며, 이를 벽을 한 번 칠했다고 정의합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;한 구역에 페인트를 여러 번 칠해도 되고 다시 칠해야 할 구역이 아닌 곳에 페인트를 칠해도 되지만 다시 칠하기로 정한 구역은 적어도 한 번 페인트칠을 해야 합니다. 예산을 아끼기 위해 다시 칠할 구역을 정했듯 마찬가지로 롤러로 페인트칠을 하는 횟수를 최소화하려고 합니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;정수 n, m과 다시 페인트를 칠하기로 정한 구역들의 번호가 담긴 정수 배열 section이 매개변수로 주어질 때 롤러로 페인트칠해야 하는 최소 횟수를 return 하는 solution 함수를 작성해 주세요.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&amp;nbsp;&lt;/h3&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;제한 사항&lt;/b&gt;&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;1 &amp;le; m &amp;le; n &amp;le; 100,000&lt;/li&gt;
&lt;li&gt;1 &amp;le; section의 길이 &amp;le; n
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;1 &amp;le; section의 원소 &amp;le; n&lt;/li&gt;
&lt;li&gt;section의 원소는 페인트를 다시 칠해야 하는 구역의 번호입니다.&lt;/li&gt;
&lt;li&gt;section에서 같은 원소가 두 번 이상 나타나지 않습니다.&lt;/li&gt;
&lt;li&gt;section의 원소는 오름차순으로 정렬되어 있습니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&amp;nbsp;&lt;/h3&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;&lt;b&gt;입출력 예&lt;/b&gt;&lt;/b&gt;&lt;/h3&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 25%; text-align: center;&quot;&gt;&lt;b&gt;n&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 25%; text-align: center;&quot;&gt;&lt;b&gt;m&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 25%; text-align: center;&quot;&gt;&lt;b&gt;section&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 25%; text-align: center;&quot;&gt;&lt;b&gt;result&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 25%; text-align: center;&quot;&gt;8&lt;/td&gt;
&lt;td style=&quot;width: 25%; text-align: center;&quot;&gt;4&lt;/td&gt;
&lt;td style=&quot;width: 25%; text-align: center;&quot;&gt;[2, 3, 6]&lt;/td&gt;
&lt;td style=&quot;width: 25%; text-align: center;&quot;&gt;2&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 25%; text-align: center;&quot;&gt;5&lt;/td&gt;
&lt;td style=&quot;width: 25%; text-align: center;&quot;&gt;4&lt;/td&gt;
&lt;td style=&quot;width: 25%; text-align: center;&quot;&gt;[1, 3]&lt;/td&gt;
&lt;td style=&quot;width: 25%; text-align: center;&quot;&gt;1&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 25%; text-align: center;&quot;&gt;4&lt;/td&gt;
&lt;td style=&quot;width: 25%; text-align: center;&quot;&gt;1&lt;/td&gt;
&lt;td style=&quot;width: 25%; text-align: center;&quot;&gt;[1, 2, 3, 4]&lt;/td&gt;
&lt;td style=&quot;width: 25%; text-align: center;&quot;&gt;4&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&amp;nbsp;&lt;/h3&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;풀이&lt;/b&gt;&lt;b&gt;&lt;/b&gt;&lt;/h3&gt;
&lt;pre id=&quot;code_1693319227359&quot; class=&quot;javascript&quot; style=&quot;background-color: #f8f8f8; color: #383a42; text-align: start;&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;function solution(n, m, section) {
  let answer = 0;
  
  // 현재까지 칠한 구역
  let part = 0;
  
  section.forEach((sec) =&amp;gt; {
 // section이 현재까지 칠한 구역보다 큰 경우
    if (sec &amp;gt; part) {
      part = sec + m - 1;
      answer++;
    }
  });
  return answer;
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;반복문을 사용하여 section을 순회하면서 section이 지금까지 칠한 구역보다 크다면 롤 크기만큼 구역을 칠해주고 칠한 구역을 업데이트 시켜준다.(페인트를 칠한 횟수 카운트 + 1)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>알고리즘/프로그래머스</category>
      <category>javascript</category>
      <category>덧칠하기</category>
      <category>코딩테스트</category>
      <category>프로그래머스</category>
      <author>후끈후끈</author>
      <guid isPermaLink="true">https://likelacoste.tistory.com/86</guid>
      <comments>https://likelacoste.tistory.com/86#entry86comment</comments>
      <pubDate>Tue, 29 Aug 2023 23:32:25 +0900</pubDate>
    </item>
    <item>
      <title>[프로그래머스] 달리기 경주 - Javascript</title>
      <link>https://likelacoste.tistory.com/85</link>
      <description>&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;문제 출처&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;​&lt;br /&gt;&lt;a href=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/178871&quot;&gt;Lv.1 달리기 경주&lt;/a&gt;&lt;br /&gt;​&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;문제 설명&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;​&lt;br /&gt;얀에서는 매년 달리기 경주가 열립니다. 해설진들은 선수들이 자기 바로 앞의 선수를 추월할 때 추월한 선수의 이름을 부릅니다. 예를 들어 1등부터 3등까지 &quot;mumu&quot;, &quot;soe&quot;, &quot;poe&quot; 선수들이 순서대로 달리고 있을 때, 해설진이 &quot;soe&quot;선수를 불렀다면 2등인 &quot;soe&quot; 선수가 1등인 &quot;mumu&quot; 선수를 추월했다는 것입니다. 즉 &quot;soe&quot; 선수가 1등, &quot;mumu&quot; 선수가 2등으로 바뀝니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;선수들의 이름이 1등부터 현재 등수 순서대로 담긴 문자열 배열 players와 해설진이 부른 이름을 담은 문자열 배열 callings가 매개변수로 주어질 때, 경주가 끝났을 때 선수들의 이름을 1등부터 등수 순서대로 배열에 담아 return 하는 solution 함수를 완성해주세요.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&amp;nbsp;&lt;/h3&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;제한 사항&lt;/b&gt;&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;5 &amp;le; players의 길이 &amp;le; 50,000
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;players[i]는 i번째 선수의 이름을 의미합니다.&lt;/li&gt;
&lt;li&gt;players의 원소들은 알파벳 소문자로만 이루어져 있습니다.&lt;/li&gt;
&lt;li&gt;players에는 중복된 값이 들어가 있지 않습니다.&lt;/li&gt;
&lt;li&gt;3 &amp;le; players[i]의 길이 &amp;le; 10&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;2 &amp;le; callings의 길이 &amp;le; 1,000,000
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;callings는 players의 원소들로만 이루어져 있습니다.&lt;/li&gt;
&lt;li&gt;경주 진행중 1등인 선수의 이름은 불리지 않습니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&amp;nbsp;&lt;/h3&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;입출력 예&lt;/b&gt;&lt;/h3&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%; height: 36px;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot;&gt;
&lt;tbody&gt;
&lt;tr style=&quot;height: 18px;&quot;&gt;
&lt;td style=&quot;width: 33.3333%; text-align: center; height: 18px;&quot;&gt;&lt;b&gt;players&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; text-align: center; height: 18px;&quot;&gt;&lt;b&gt;callings&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; text-align: center; height: 18px;&quot;&gt;&lt;b&gt;result&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 18px;&quot;&gt;
&lt;td style=&quot;width: 33.3333%; text-align: center; height: 18px;&quot;&gt;[&quot;mumu&quot;,&amp;nbsp;&quot;soe&quot;,&amp;nbsp;&quot;poe&quot;,&amp;nbsp;&quot;kai&quot;,&amp;nbsp;&quot;mine&quot;]&lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; text-align: center; height: 18px;&quot;&gt;[&quot;kai&quot;,&amp;nbsp;&quot;kai&quot;,&amp;nbsp;&quot;mine&quot;,&amp;nbsp;&quot;mine&quot;] &lt;/td&gt;
&lt;td style=&quot;width: 33.3333%; text-align: center; height: 18px;&quot;&gt;[&quot;mumu&quot;,&amp;nbsp;&quot;kai&quot;,&amp;nbsp;&quot;mine&quot;,&amp;nbsp;&quot;soe&quot;,&amp;nbsp;&quot;poe&quot;]&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;입출력 예 설명&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;입출력 예 #1&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;4등인&amp;nbsp;&quot;kai&quot;&amp;nbsp;선수가&amp;nbsp;2번&amp;nbsp;추월하여&amp;nbsp;2등이&amp;nbsp;되고&amp;nbsp;앞서&amp;nbsp;3등,&amp;nbsp;2등인&amp;nbsp;&quot;poe&quot;,&amp;nbsp;&quot;soe&quot;&amp;nbsp;선수는&amp;nbsp;4등,&amp;nbsp;3등이&amp;nbsp;됩니다.&amp;nbsp;5등인&amp;nbsp;&quot;mine&quot;&amp;nbsp;선수가&amp;nbsp;2번&amp;nbsp;추월하여&amp;nbsp;4등,&amp;nbsp;3등인&amp;nbsp;&quot;poe&quot;,&amp;nbsp;&quot;soe&quot;&amp;nbsp;선수가&amp;nbsp;5등,&amp;nbsp;4등이&amp;nbsp;되고&amp;nbsp;경주가&amp;nbsp;끝납니다.&amp;nbsp;1등부터&amp;nbsp;배열에&amp;nbsp;담으면&amp;nbsp;[&quot;mumu&quot;,&amp;nbsp;&quot;kai&quot;,&amp;nbsp;&quot;mine&quot;,&amp;nbsp;&quot;soe&quot;,&amp;nbsp;&quot;poe&quot;]이&amp;nbsp;됩니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;풀이&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아래와 같이 callings 배열을 순회하면서 이름이 불린 player에 대한 indexOf를 사용하여 이전에 위치한 player와 이름이 불린 player의 위치를 변경하면 문제를 해결할 수 있다.&lt;/p&gt;
&lt;pre id=&quot;code_1693213653483&quot; style=&quot;background-color: #f8f8f8; color: #383a42; text-align: start;&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;function solution(players, callings){
    const playersArr = [...players];

    callings.forEach((callingPlayer)=&amp;gt;{
        const callingPlayerIndex = playersArr.indexOf(callingPlayer);
        const prevPlayer = playersArr[callingPlayerIndex - 1]; 

        playersArr[callingPlayerIndex] = prevPlayer;
        playersArr[callingPlayerIndex - 1] = callingPlayer;
    })
    return playersArr;
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하지만 시간 초과로 인해 통과되지 않는 것을 볼 수 있다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2023-08-28 18.08.18.png&quot; data-origin-width=&quot;577&quot; data-origin-height=&quot;197&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b5VYFu/btssqCxrb5e/ehy7dbKAA5jhJP8TKnmWy1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b5VYFu/btssqCxrb5e/ehy7dbKAA5jhJP8TKnmWy1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b5VYFu/btssqCxrb5e/ehy7dbKAA5jhJP8TKnmWy1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb5VYFu%2FbtssqCxrb5e%2Fehy7dbKAA5jhJP8TKnmWy1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;577&quot; height=&quot;197&quot; data-filename=&quot;스크린샷 2023-08-28 18.08.18.png&quot; data-origin-width=&quot;577&quot; data-origin-height=&quot;197&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이는 indexOf 매서드의 시간 복잡도는 O(n^2) 이기 때문에 시간 초과가 되는 것이라 생각된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그래서 이 문제의 접근을 아래와 같이 hash 자료구조를 이용하여 풀어보았다. (배열의 인덱스가 아닌 객체의 키로 접근하는 방법을 생각하였다.)&lt;/p&gt;
&lt;pre id=&quot;code_1693213951162&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;function solution(players, callings) {
    const hash = new Map();

    players.forEach((player, idx) =&amp;gt; {
        hash.set(player, idx);
    });
    
    callings.forEach((name) =&amp;gt; {
        const callNameIdx = hash.get(name);
        const frontPlayer = players[callNameIdx-1];

        [players[callNameIdx], players[callNameIdx-1]] = [players[callNameIdx-1], players[callNameIdx]];

        hash.set(name, hash.get(name) - 1);
        hash.set(frontPlayer, hash.get(name) + 1);
    });
    return players;
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;먼저 players를 순회하면서 player의 이름을 key로, player의 index를 value로 초기화하였다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그런 다음 앞에서 풀이한 방법 대로 이름이 불린 player의 index를 가지고 players 배열에서 이전의 선수를 찾은 후 위치를 변경하였다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이렇게 푼 결과 문제를 통과할 수 있었다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2023-08-28 18.17.30.png&quot; data-origin-width=&quot;413&quot; data-origin-height=&quot;449&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/kBqqz/btssqoF9WnJ/wFGOakYMKxHnSgpknBnpQ0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/kBqqz/btssqoF9WnJ/wFGOakYMKxHnSgpknBnpQ0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/kBqqz/btssqoF9WnJ/wFGOakYMKxHnSgpknBnpQ0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FkBqqz%2FbtssqoF9WnJ%2FwFGOakYMKxHnSgpknBnpQ0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;413&quot; height=&quot;449&quot; data-filename=&quot;스크린샷 2023-08-28 18.17.30.png&quot; data-origin-width=&quot;413&quot; data-origin-height=&quot;449&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;해당 문제를 통해 배열의 index를 찾아주는 indexOf 매서드를 사용할 때 시간 복잡도를 생각해봐야한다는 것을 생각해볼 수 있었다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>알고리즘/프로그래머스</category>
      <category>indexOf</category>
      <category>javascript</category>
      <category>달리기 경주</category>
      <category>알고리즘</category>
      <category>프로그래머스</category>
      <author>후끈후끈</author>
      <guid isPermaLink="true">https://likelacoste.tistory.com/85</guid>
      <comments>https://likelacoste.tistory.com/85#entry85comment</comments>
      <pubDate>Mon, 28 Aug 2023 18:23:07 +0900</pubDate>
    </item>
    <item>
      <title>[프로그래머스] 평균 구하기 - Javascript</title>
      <link>https://likelacoste.tistory.com/84</link>
      <description>&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;문제 출처&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://school.programmers.co.kr/learn/courses/30/lessons/12944?language=javascript&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;Lv.1 평균 구하기&lt;/a&gt;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&amp;nbsp;&lt;/h3&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;문제 설명&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;정수를 담고 있는 배열 arr의 평균값을 return하는 함수, solution을 완성해보세요.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&amp;nbsp;&lt;/h3&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;제한 사항&lt;/b&gt;&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;arr은 길이 1 이상, 100 이하인 배열입니다.&lt;/li&gt;
&lt;li&gt;arr의 원소는 -10,000 이상 10,000 이하인 정수입니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&amp;nbsp;&lt;/h3&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;예시&lt;/b&gt;&lt;/h3&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%; height: 54px;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot; data-ke-style=&quot;style11&quot;&gt;
&lt;tbody&gt;
&lt;tr style=&quot;height: 18px;&quot;&gt;
&lt;td style=&quot;width: 50%; text-align: center; height: 18px;&quot;&gt;&lt;b&gt;arr&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;width: 50%; text-align: center; height: 18px;&quot;&gt;&lt;b&gt;return&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 18px;&quot;&gt;
&lt;td style=&quot;width: 50%; text-align: center; height: 18px;&quot;&gt;[1, 2, 3, 4]&lt;/td&gt;
&lt;td style=&quot;width: 50%; text-align: center; height: 18px;&quot;&gt;2.5&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 18px;&quot;&gt;
&lt;td style=&quot;width: 50%; text-align: center; height: 18px;&quot;&gt;[5, 5]&lt;/td&gt;
&lt;td style=&quot;width: 50%; text-align: center; height: 18px;&quot;&gt;5&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&amp;nbsp;&lt;/h3&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;풀이&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;숫자들의 평균을 구하는 문제이다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;1. 배열 안에 있는 요소들의 합을 구한다.&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;2. 요소들의 합을 요소의 개수(배열의 길이)로 나눈다.&lt;/p&gt;
&lt;pre id=&quot;code_1693033550703&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;function solution(arr){
  // 배열 안에 있는 숫자들의 합
  let totalSum = arr.reduce((acc, cur) =&amp;gt; acc + cur, 0); 
  
  // 배열의 길이(전체 수의 개수)
  let arrLength = arr.length;    
  
  return totalSum / arrLength;
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위 풀이를 아래와 같이 조금 더 간단하게 작성할 수도 있다.&lt;/p&gt;
&lt;pre id=&quot;code_1693033708508&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;function solution(arr) {
  return arr.reduce((sum, current) =&amp;gt; sum + current) / arr.length;
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>알고리즘/프로그래머스</category>
      <category>javascript</category>
      <category>알고리즘</category>
      <category>자바스크립트</category>
      <category>평균 구하기</category>
      <category>프로그래머스</category>
      <author>후끈후끈</author>
      <guid isPermaLink="true">https://likelacoste.tistory.com/84</guid>
      <comments>https://likelacoste.tistory.com/84#entry84comment</comments>
      <pubDate>Sat, 26 Aug 2023 16:11:56 +0900</pubDate>
    </item>
    <item>
      <title>제네릭(Generic)</title>
      <link>https://likelacoste.tistory.com/83</link>
      <description>&lt;h1&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;제네릭이란&lt;/span&gt;&lt;/b&gt;&lt;/h1&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;타입스크립트에서 &lt;b&gt;제네릭이란&lt;/b&gt; &lt;u&gt;함수나 인터페이스, 타입 별칭, 클레스 등을 다양한 타입과 함께 동작하도록 만들어 주는 기능&lt;/u&gt;을 말합니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;제네릭(Generic)이란 일반적인 또는 포괄적인 이라는 뜻을 가지고 있습니다. 제네릭과 의미가 비슷한 단어는 제네럴(General)입니다. 제네럴은 영어권에서 종합병원을 이야기 할 때 사용되는 단어로, 두루두루 다 적용할 수 있는 포괄적인 뜻으로 생각할 수 있습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;제네릭이 필요한 상황&lt;/span&gt;&lt;/b&gt;&lt;/h2&gt;
&lt;pre class=&quot;typescript&quot; data-ke-language=&quot;typescript&quot;&gt;&lt;code&gt;function example(value:any){
    return value
};

let numberValue = example(123); // any 타입
let stringValue = example('Korea'); // any 타입&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;&lt;code&gt;example&lt;/code&gt;함수는 인수로 전달한 값을 그대로 반환하는 함수입니다. 따라서 변수 &lt;code&gt;numberValue&lt;/code&gt;에는 123이 저장되고, 변수 &lt;code&gt;stringValue&lt;/code&gt;에는 'Korea'이 저장됩니다. 여기서 타입스크립트는 &lt;code&gt;numberValue&lt;/code&gt;와 &lt;code&gt;stringValue&lt;/code&gt; 변수의 타입을 각각 number, string이 아닌 any타입으로 추정하게 됩니다. 이는 &lt;code&gt;example&lt;/code&gt; 함수의 반환값 타입을 return 문을 기준으로 추론하기 때문입니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2023-08-14 15.30.47.png&quot; data-origin-width=&quot;766&quot; data-origin-height=&quot;206&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bScGGp/btsrgoUoKDB/MN7FlPq5J5Bv9cWV5O6u4K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bScGGp/btsrgoUoKDB/MN7FlPq5J5Bv9cWV5O6u4K/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bScGGp/btsrgoUoKDB/MN7FlPq5J5Bv9cWV5O6u4K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbScGGp%2FbtsrgoUoKDB%2FMN7FlPq5J5Bv9cWV5O6u4K%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;666&quot; height=&quot;179&quot; data-filename=&quot;스크린샷 2023-08-14 15.30.47.png&quot; data-origin-width=&quot;766&quot; data-origin-height=&quot;206&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;이렇게 함수 호출 결과를 저장하는 &lt;code&gt;numberValue&lt;/code&gt;, &lt;code&gt;stringValue&lt;/code&gt; 등의 변수가 any 타입으로 추론되면 아래와 같은 문제가 발생하게 됩니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2023-08-14 15.39.59.png&quot; data-origin-width=&quot;956&quot; data-origin-height=&quot;496&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/5Orkd/btsrfiNFifC/AtVxVVBhqw4kbK25ilPsfk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/5Orkd/btsrfiNFifC/AtVxVVBhqw4kbK25ilPsfk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/5Orkd/btsrfiNFifC/AtVxVVBhqw4kbK25ilPsfk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F5Orkd%2FbtsrfiNFifC%2FAtVxVVBhqw4kbK25ilPsfk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;666&quot; height=&quot;346&quot; data-filename=&quot;스크린샷 2023-08-14 15.39.59.png&quot; data-origin-width=&quot;956&quot; data-origin-height=&quot;496&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;&lt;code&gt;numberValue&lt;/code&gt;에는 number 타입의 값 123이 저장되어 있지만, any 타입으로 추론되었기 때문에 string타입의 메서드인 &lt;code&gt;toUpperCase&lt;/code&gt;를 사용해도 오류를 감지하지 못합니다. 이러한 코드를 실제로 실행하면 런타임 오류를 발생시키게 됩니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;이런 경우에 제네릭을 사용하면 문제를 해결할 수 있습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;제네릭 함수&lt;/span&gt;&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;제네릭 함수는 다음과 같이 선언할 수 있습니다.&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;typescript&quot; data-ke-language=&quot;typescript&quot;&gt;&lt;code&gt;function example&amp;lt;T&amp;gt;(value:T):T {
    return value
};

let numberValue = example(123); // number 타입
let stringValue = example('Korea'); // string 타입&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;함수 이름 뒤에 꺽쇠(&amp;lt;&amp;gt;)를 열고 타입을 담는 변수인 타입 변수 T를 선언한 후, 매개변수와 반환 값의 타입을 이 타입변수 T로 설정합니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;T에 어떤 타입이 할당될 지는 함수가 호출될 때 결정됩니다. &lt;code&gt;example(123)&lt;/code&gt;처럼 number 타입의 값을 인수로 전달하게 되면 매개변수 value에 number 타입의 값이 저장되면서 타입스크립트는 T를 number 타입으로 추론하게 됩니다. 그럼 이때의 &lt;code&gt;example&lt;/code&gt; 함수의 반환 값 타입 또한 number 타입이 됩니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;제네릭을 사용하게 되면 변수의 타입이 any로 추론되는 것을 방지할 수 있으며 잘못된 메서드 사용을 찾아내는 것을 볼 수 있습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2023-08-14 15.51.11.png&quot; data-origin-width=&quot;1448&quot; data-origin-height=&quot;562&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/caVisC/btsq1bWU6KG/ELjKN1vrxstPyVm1ZTgkBk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/caVisC/btsq1bWU6KG/ELjKN1vrxstPyVm1ZTgkBk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/caVisC/btsq1bWU6KG/ELjKN1vrxstPyVm1ZTgkBk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcaVisC%2Fbtsq1bWU6KG%2FELjKN1vrxstPyVm1ZTgkBk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;666&quot; height=&quot;258&quot; data-filename=&quot;스크린샷 2023-08-14 15.51.11.png&quot; data-origin-width=&quot;1448&quot; data-origin-height=&quot;562&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;제네릭 함수를 호출할 때 다음과 같이 타입 변수에 할당할 타입을 직접 명시하는 것도 가능합니다.&lt;/span&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;typescript&quot; data-ke-language=&quot;typescript&quot;&gt;&lt;code&gt;function func&amp;lt;T&amp;gt;(value: T): T {
  return value;
}

let arr = func&amp;lt;[number, number, number]&amp;gt;([1, 2, 3]);&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;만약 위 코드에서 타입 변수에 할당할 타입을 튜플 타입으로 설정하지 않았다면 T가 &lt;code&gt;number[]&lt;/code&gt;타입으로 추론되었을 것입니다. (타입스크립트는 타입을 추론할 때 항상 일방적이로 범용적인 타입으로 추론하기 때문) 타입 변수에 할당하고 싶은 특정 타입이 존재한다면 함수 호출과 함께 직접 명시해주는 것이 좋습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;응용하기&lt;/span&gt;&lt;/b&gt;&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;사례1 - 2개의 타입 변수&lt;/span&gt;&lt;/b&gt;&lt;/h3&gt;
&lt;pre class=&quot;typescript&quot; data-ke-language=&quot;typescript&quot;&gt;&lt;code&gt;function exam&amp;lt;T, U&amp;gt;(a: T, b: U) {
  return [b, a];
}

const [a, b] = exam(&quot;1&quot;, 2);&lt;/code&gt;&lt;/pre&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&amp;nbsp;&lt;/h3&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;사례2 - 다양한 배열 타입을 인수로 받는 제네릭 함수&lt;/span&gt;&lt;/b&gt;&lt;/h3&gt;
&lt;pre class=&quot;javascript&quot;&gt;&lt;code&gt;function returnFirstValue&amp;lt;T&amp;gt;(data: T[]) {
  return data[0];
}

let num = returnFirstValue([0, 1, 2]);
// number

let str = returnFirstValue([1, &quot;hello&quot;, &quot;mynameis&quot;]);
// number | string&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;returnFirstValue함수를 처음 호출했을 때는 인수로 number[] 타입의 값을 전달했기 때문에 T는 number 타입으로 추론됩니다. 반면에 두번째로 호출 했을 때는 인수로 (number | string)[]타입의 값을 전달했기 때문에 T는 number | string 타입으로 추론됩니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;만약 반환값의 타입을 배열의 첫번째 요소의 타입이 되도록 하고 싶다면, 다음과 같이 튜플 타입과 나머지 파라미터를 이용하면 됩니다.&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;typescript&quot; data-ke-language=&quot;typescript&quot;&gt;&lt;code&gt;function returnFirstValue&amp;lt;T&amp;gt;(data: [T, ...unknown[]]) {
  return data[0];
}

let str = returnFirstValue([1, &quot;hello&quot;, &quot;mynameis&quot;]);
// number&lt;/code&gt;&lt;/pre&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&amp;nbsp;&lt;/h3&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;사례3 - 타입 변수를 제한&lt;/span&gt;&lt;/b&gt;&lt;/h3&gt;
&lt;pre class=&quot;typescript&quot; data-ke-language=&quot;typescript&quot;&gt;&lt;code&gt;function getLength&amp;lt;T extends { length: number }&amp;gt;(data: T) {
  return data.length;
}

getLength(&quot;123&quot;);            //  

getLength([1, 2, 3]);        //  

getLength({ length: 1 });    //  

getLength(100);              // ❌

getLength(undefined);        // ❌

getLength(null);             // ❌&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;타입 변수를 제한할 때는 &lt;b&gt;extends(확장)&lt;/b&gt;를 이용합니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;위와 같이 &lt;code&gt;T extends { length: number }&lt;/code&gt;라고 정의하면 T는 number 타입의 프로퍼티 length를 가지고 있는 타입이어야 합니다. 때문에 number, undefined, null과 같이 프로퍼티로 length를 가지고 있지 않는 타입은 오류를 발생하게 됩니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>TypeScript</category>
      <category>Generic</category>
      <category>Typescript</category>
      <category>제네릭</category>
      <category>타입스크립트</category>
      <author>후끈후끈</author>
      <guid isPermaLink="true">https://likelacoste.tistory.com/83</guid>
      <comments>https://likelacoste.tistory.com/83#entry83comment</comments>
      <pubDate>Mon, 14 Aug 2023 16:25:15 +0900</pubDate>
    </item>
    <item>
      <title>컴파일러 옵션</title>
      <link>https://likelacoste.tistory.com/82</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;&lt;b&gt;컴파일러 옵션이란&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;타입스크립트의 컴파일은 작성한 타입스크립트 코드에 타입 오류가 없는지를 검사하고 오류가 없다면 자바스크립트 코드로 변환합니다. 이러한 컴파일 과정에서 아주 세부적인 사항들(얼마나 엄격하게 타입을 검사할 건지 또는 컴파일 되는 자바스크립트 코드의 버전은 어떻게 할 건지 등)을 컴파일 옵션이라고 합니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;&lt;b&gt;컴파일러 옵션 자동 생성&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;타입스크립트의 컴파일러 옵션은 &lt;code&gt;tsconfig.json&lt;/code&gt; 파일에서 설정할 수 있으며, Node.js 패키지 단위로 설정됩니다. 컴파일러 옵션을 가장 쉽게 설정하는 방법은 자동 생성 도구를 이용하는 방법입니다. &lt;code&gt;tsc&lt;/code&gt;를 이용하면 기본 옵션이 설정된 컴파일러 옵션 파일을 자동 생성할 수 있습니다.&lt;/span&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre class=&quot;ada&quot;&gt;&lt;code&gt;tsc --init&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;터미널에서 위 명령어를 입력하면 자동으로 기본 설정이 완료된 &lt;code&gt;tsconfig.json&lt;/code&gt; 파일이 생성됩니다.&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;nix&quot;&gt;&lt;code&gt;{
  &quot;compilerOptions&quot;: {
    /* Visit https://aka.ms/tsconfig to read more about this file */

    /* Projects */
    // &quot;incremental&quot;: true,                              /* Save .tsbuildinfo files to allow for incremental compilation of projects. */
    // &quot;composite&quot;: true,                                /* Enable constraints that allow a TypeScript project to be used with project references. */
    // &quot;tsBuildInfoFile&quot;: &quot;./.tsbuildinfo&quot;,              /* Specify the path to .tsbuildinfo incremental compilation file. */
    // &quot;disableSourceOfProjectReferenceRedirect&quot;: true,  /* Disable preferring source files instead of declaration files when referencing composite projects. */
    // &quot;disableSolutionSearching&quot;: true,                 /* Opt a project out of multi-project reference checking when editing. */
    // &quot;disableReferencedProjectLoad&quot;: true,             /* Reduce the number of projects loaded automatically by TypeScript. */

    /* Language and Environment */
    &quot;target&quot;: &quot;es2016&quot;,                                  /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */
    // &quot;lib&quot;: [],                                        /* Specify a set of bundled library declaration files that describe the target runtime environment. */
    // &quot;jsx&quot;: &quot;preserve&quot;,                                /* Specify what JSX code is generated. */
    // &quot;experimentalDecorators&quot;: true,                   /* Enable experimental support for legacy experimental decorators. */
    // &quot;emitDecoratorMetadata&quot;: true,                    /* Emit design-type metadata for decorated declarations in source files. */
    // &quot;jsxFactory&quot;: &quot;&quot;,                                 /* Specify the JSX factory function used when targeting React JSX emit, e.g. 'React.createElement' or 'h'. */
    // &quot;jsxFragmentFactory&quot;: &quot;&quot;,                         /* Specify the JSX Fragment reference used for fragments when targeting React JSX emit e.g. 'React.Fragment' or 'Fragment'. */
    // &quot;jsxImportSource&quot;: &quot;&quot;,                            /* Specify module specifier used to import the JSX factory functions when using 'jsx: react-jsx*'. */
    // &quot;reactNamespace&quot;: &quot;&quot;,                             /* Specify the object invoked for 'createElement'. This only applies when targeting 'react' JSX emit. */
    // &quot;noLib&quot;: true,                                    /* Disable including any library files, including the default lib.d.ts. */
    // &quot;useDefineForClassFields&quot;: true,                  /* Emit ECMAScript-standard-compliant class fields. */
    // &quot;moduleDetection&quot;: &quot;auto&quot;,                        /* Control what method is used to detect module-format JS files. */

    /* Modules */
    &quot;module&quot;: &quot;commonjs&quot;,                                /* Specify what module code is generated. */
    // &quot;rootDir&quot;: &quot;./&quot;,                                  /* Specify the root folder within your source files. */
    // &quot;moduleResolution&quot;: &quot;node10&quot;,                     /* Specify how TypeScript looks up a file from a given module specifier. */
    // &quot;baseUrl&quot;: &quot;./&quot;,                                  /* Specify the base directory to resolve non-relative module names. */
    // &quot;paths&quot;: {},                                      /* Specify a set of entries that re-map imports to additional lookup locations. */
    // &quot;rootDirs&quot;: [],                                   /* Allow multiple folders to be treated as one when resolving modules. */
    // &quot;typeRoots&quot;: [],                                  /* Specify multiple folders that act like './node_modules/@types'. */
    // &quot;types&quot;: [],                                      /* Specify type package names to be included without being referenced in a source file. */
    // &quot;allowUmdGlobalAccess&quot;: true,                     /* Allow accessing UMD globals from modules. */
    // &quot;moduleSuffixes&quot;: [],                             /* List of file name suffixes to search when resolving a module. */
    // &quot;allowImportingTsExtensions&quot;: true,               /* Allow imports to include TypeScript file extensions. Requires '--moduleResolution bundler' and either '--noEmit' or '--emitDeclarationOnly' to be set. */
    // &quot;resolvePackageJsonExports&quot;: true,                /* Use the package.json 'exports' field when resolving package imports. */
    // &quot;resolvePackageJsonImports&quot;: true,                /* Use the package.json 'imports' field when resolving imports. */
    // &quot;customConditions&quot;: [],                           /* Conditions to set in addition to the resolver-specific defaults when resolving imports. */
    // &quot;resolveJsonModule&quot;: true,                        /* Enable importing .json files. */
    // &quot;allowArbitraryExtensions&quot;: true,                 /* Enable importing files with any extension, provided a declaration file is present. */
    // &quot;noResolve&quot;: true,                                /* Disallow 'import's, 'require's or '&amp;lt;reference&amp;gt;'s from expanding the number of files TypeScript should add to a project. */

    /* JavaScript Support */
    // &quot;allowJs&quot;: true,                                  /* Allow JavaScript files to be a part of your program. Use the 'checkJS' option to get errors from these files. */
    // &quot;checkJs&quot;: true,                                  /* Enable error reporting in type-checked JavaScript files. */
    // &quot;maxNodeModuleJsDepth&quot;: 1,                        /* Specify the maximum folder depth used for checking JavaScript files from 'node_modules'. Only applicable with 'allowJs'. */

    /* Emit */
    // &quot;declaration&quot;: true,                              /* Generate .d.ts files from TypeScript and JavaScript files in your project. */
    // &quot;declarationMap&quot;: true,                           /* Create sourcemaps for d.ts files. */
    // &quot;emitDeclarationOnly&quot;: true,                      /* Only output d.ts files and not JavaScript files. */
    // &quot;sourceMap&quot;: true,                                /* Create source map files for emitted JavaScript files. */
    // &quot;inlineSourceMap&quot;: true,                          /* Include sourcemap files inside the emitted JavaScript. */
    // &quot;outFile&quot;: &quot;./&quot;,                                  /* Specify a file that bundles all outputs into one JavaScript file. If 'declaration' is true, also designates a file that bundles all .d.ts output. */
    // &quot;outDir&quot;: &quot;./&quot;,                                   /* Specify an output folder for all emitted files. */
    // &quot;removeComments&quot;: true,                           /* Disable emitting comments. */
    // &quot;noEmit&quot;: true,                                   /* Disable emitting files from a compilation. */
    // &quot;importHelpers&quot;: true,                            /* Allow importing helper functions from tslib once per project, instead of including them per-file. */
    // &quot;importsNotUsedAsValues&quot;: &quot;remove&quot;,               /* Specify emit/checking behavior for imports that are only used for types. */
    // &quot;downlevelIteration&quot;: true,                       /* Emit more compliant, but verbose and less performant JavaScript for iteration. */
    // &quot;sourceRoot&quot;: &quot;&quot;,                                 /* Specify the root path for debuggers to find the reference source code. */
    // &quot;mapRoot&quot;: &quot;&quot;,                                    /* Specify the location where debugger should locate map files instead of generated locations. */
    // &quot;inlineSources&quot;: true,                            /* Include source code in the sourcemaps inside the emitted JavaScript. */
    // &quot;emitBOM&quot;: true,                                  /* Emit a UTF-8 Byte Order Mark (BOM) in the beginning of output files. */
    // &quot;newLine&quot;: &quot;crlf&quot;,                                /* Set the newline character for emitting files. */
    // &quot;stripInternal&quot;: true,                            /* Disable emitting declarations that have '@internal' in their JSDoc comments. */
    // &quot;noEmitHelpers&quot;: true,                            /* Disable generating custom helper functions like '__extends' in compiled output. */
    // &quot;noEmitOnError&quot;: true,                            /* Disable emitting files if any type checking errors are reported. */
    // &quot;preserveConstEnums&quot;: true,                       /* Disable erasing 'const enum' declarations in generated code. */
    // &quot;declarationDir&quot;: &quot;./&quot;,                           /* Specify the output directory for generated declaration files. */
    // &quot;preserveValueImports&quot;: true,                     /* Preserve unused imported values in the JavaScript output that would otherwise be removed. */

    /* Interop Constraints */
    // &quot;isolatedModules&quot;: true,                          /* Ensure that each file can be safely transpiled without relying on other imports. */
    // &quot;verbatimModuleSyntax&quot;: true,                     /* Do not transform or elide any imports or exports not marked as type-only, ensuring they are written in the output file's format based on the 'module' setting. */
    // &quot;allowSyntheticDefaultImports&quot;: true,             /* Allow 'import x from y' when a module doesn't have a default export. */
    &quot;esModuleInterop&quot;: true,                             /* Emit additional JavaScript to ease support for importing CommonJS modules. This enables 'allowSyntheticDefaultImports' for type compatibility. */
    // &quot;preserveSymlinks&quot;: true,                         /* Disable resolving symlinks to their realpath. This correlates to the same flag in node. */
    &quot;forceConsistentCasingInFileNames&quot;: true,            /* Ensure that casing is correct in imports. */

    /* Type Checking */
    &quot;strict&quot;: true,                                      /* Enable all strict type-checking options. */
    // &quot;noImplicitAny&quot;: true,                            /* Enable error reporting for expressions and declarations with an implied 'any' type. */
    // &quot;strictNullChecks&quot;: true,                         /* When type checking, take into account 'null' and 'undefined'. */
    // &quot;strictFunctionTypes&quot;: true,                      /* When assigning functions, check to ensure parameters and the return values are subtype-compatible. */
    // &quot;strictBindCallApply&quot;: true,                      /* Check that the arguments for 'bind', 'call', and 'apply' methods match the original function. */
    // &quot;strictPropertyInitialization&quot;: true,             /* Check for class properties that are declared but not set in the constructor. */
    // &quot;noImplicitThis&quot;: true,                           /* Enable error reporting when 'this' is given the type 'any'. */
    // &quot;useUnknownInCatchVariables&quot;: true,               /* Default catch clause variables as 'unknown' instead of 'any'. */
    // &quot;alwaysStrict&quot;: true,                             /* Ensure 'use strict' is always emitted. */
    // &quot;noUnusedLocals&quot;: true,                           /* Enable error reporting when local variables aren't read. */
    // &quot;noUnusedParameters&quot;: true,                       /* Raise an error when a function parameter isn't read. */
    // &quot;exactOptionalPropertyTypes&quot;: true,               /* Interpret optional property types as written, rather than adding 'undefined'. */
    // &quot;noImplicitReturns&quot;: true,                        /* Enable error reporting for codepaths that do not explicitly return in a function. */
    // &quot;noFallthroughCasesInSwitch&quot;: true,               /* Enable error reporting for fallthrough cases in switch statements. */
    // &quot;noUncheckedIndexedAccess&quot;: true,                 /* Add 'undefined' to a type when accessed using an index. */
    // &quot;noImplicitOverride&quot;: true,                       /* Ensure overriding members in derived classes are marked with an override modifier. */
    // &quot;noPropertyAccessFromIndexSignature&quot;: true,       /* Enforces using indexed accessors for keys declared using an indexed type. */
    // &quot;allowUnusedLabels&quot;: true,                        /* Disable error reporting for unused labels. */
    // &quot;allowUnreachableCode&quot;: true,                     /* Disable error reporting for unreachable code. */

    /* Completeness */
    // &quot;skipDefaultLibCheck&quot;: true,                      /* Skip type checking .d.ts files that are included with TypeScript. */
    &quot;skipLibCheck&quot;: true                                 /* Skip type checking all .d.ts files. */
  }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;만들어진 &lt;code&gt;sconfig.json&lt;/code&gt; 파일은 굉장히 많은 옵션들이 담겨있지만 대부분 주석처리되어 있어서 실제 적용되는 옵션은 몇개 없는 것을 볼 수 있습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;컴파일러 옵션 직접 설정하기&lt;/span&gt;&lt;/b&gt;&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;include&lt;/span&gt;&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;&lt;code&gt;include&lt;/code&gt; 옵션은 &lt;code&gt;tsc&lt;/code&gt;에게 컴파일 할 타입스크립트 파일의 범위와 위치를 알려주는 옵션입니다.&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;json&quot;&gt;&lt;code&gt;{
  &quot;include&quot;: [&quot;src&quot;]
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;위와 같이 &lt;code&gt;include&lt;/code&gt; 옵션을 설정하면 파일 하나하나 직접 컴파일하지 않고 &lt;code&gt;src&lt;/code&gt; 폴더 아래에 있는 모든 타입스크립트 파일이 동시에 컴파일 할 수 있습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;target&lt;/span&gt;&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;&lt;code&gt;target&lt;/code&gt; 옵션은 컴파일 결과 생성되는 자바스크립트 코드의 버전을 설정하는 옵션입니다.&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;json&quot;&gt;&lt;code&gt;{
  &quot;compilerOptions&quot;: {
    &quot;target&quot;: &quot;ES5&quot;
  },
  &quot;include&quot;: [&quot;src&quot;]
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;&lt;code&gt;target&lt;/code&gt; 옵션을 ES5으로 설정하면 컴파일 된 자바스크립트 코드는 ES5 버전의 자바스크립트 코드로 변환됩니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;ES6의 문법 중 하나인 화살표 함수를 작성한 후&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;autoit&quot;&gt;&lt;code&gt;const func = () =&amp;gt; console.log(&quot;Hello&quot;);&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;해당 타입스크립트 파일을 컴파일 하면 다음과 같이 화살표 함수가 함수 표현식으로 변환되는 걸 확인할 수 있습니다.&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;autoit&quot;&gt;&lt;code&gt;const func = function(){
    console.log(&quot;Hello&quot;);
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;변환되는 자바스크립트의 버전을 최신 버전으로 하고 싶다면 &lt;code&gt;target&lt;/code&gt; 옵션을 &lt;code&gt;ESNext&lt;/code&gt;로 설정하면 됩니다.&lt;/span&gt;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&amp;nbsp;&lt;/h3&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;module&lt;/span&gt;&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;&lt;code&gt;module&lt;/code&gt; 옵션은 변환되는 자바스크립트 코드의 모듈 시스템을 설정하는 옵션입니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre class=&quot;json&quot;&gt;&lt;code&gt;{
  &quot;compilerOptions&quot;: {
    &quot;target&quot;: &quot;ESNext&quot;,
        &quot;module&quot;: &quot;CommonJS&quot;
  },
  &quot;include&quot;: [&quot;src&quot;]
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;위와 같이 &lt;code&gt;module&lt;/code&gt; 옵션을 &lt;code&gt;CommonJS&lt;/code&gt;로 설정하면 변환되는 자바스크립트 코드의 모듈을 &lt;code&gt;CommonJS&lt;/code&gt; 문법으로 변환시킬 수 있습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre class=&quot;javascript&quot;&gt;&lt;code&gt;// hello.ts

export const hello = () =&amp;gt; {
  console.log(&quot;hello&quot;);
};&lt;/code&gt;&lt;/pre&gt;
&lt;pre class=&quot;clean&quot;&gt;&lt;code&gt;// index.ts

import { hello } from &quot;./hello&quot;;

hello();&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;&lt;code&gt;index.ts&lt;/code&gt; 파일과 &lt;code&gt;hello.ts&lt;/code&gt;파일에 import와 export를 사용해서 코드를 작성한 후에 &lt;code&gt;tsc&lt;/code&gt;로 컴파일 하면 아래와 같이 CommonJS 문법으로 변환되는 것을 볼 수 있습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre class=&quot;javascript&quot;&gt;&lt;code&gt;// index.js

&quot;use strict&quot;;
Object.defineProperty(exports, &quot;__esModule&quot;, { value: true });
const hello_1 = require(&quot;./hello&quot;);
(0, hello_1.hello)();&lt;/code&gt;&lt;/pre&gt;
&lt;pre class=&quot;javascript&quot;&gt;&lt;code&gt;// hello.js

&quot;use strict&quot;;
Object.defineProperty(exports, &quot;__esModule&quot;, { value: true });
exports.hello = void 0;
const hello = () =&amp;gt; {
    console.log(&quot;hello&quot;);
};
exports.hello = hello;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;&lt;code&gt;module&lt;/code&gt; 옵션을 &lt;code&gt;ESNext&lt;/code&gt;로 설정하면 자바스크립트 코드가 ES 모듈 시스템을 사용하는 것을 볼 수 있습니다.&lt;/span&gt;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&amp;nbsp;&lt;/h3&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;outDir&lt;/span&gt;&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;&lt;code&gt;outDir&lt;/code&gt; 옵션은 컴파일 결과를 생성할 자바스크립트 코드의 위치를 결정하는 옵션입니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre class=&quot;clojure&quot;&gt;&lt;code&gt;{
  &quot;compilerOptions&quot;: {
        ...
    &quot;outDir&quot;: &quot;dist&quot;
  },
  &quot;include&quot;: [&quot;src&quot;]
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;&lt;code&gt;tsc&lt;/code&gt;를 이용해 컴파일 하면 컴파일 결과가 &lt;code&gt;dist&lt;/code&gt; 폴더에 생성되는 것을 볼 수 있습니다.&lt;/span&gt;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&amp;nbsp;&lt;/h3&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;strict&lt;/span&gt;&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;&lt;code&gt;strict&lt;/code&gt; 옵션은 타입스크립트 컴파일러의 타입 검사 엄격함의 수준을 정하는 옵션입니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre class=&quot;clojure&quot;&gt;&lt;code&gt;{
  &quot;compilerOptions&quot;: {
    ...
    &quot;strict&quot;: true
  },
  &quot;include&quot;: [&quot;src&quot;]
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;&lt;code&gt;strict&lt;/code&gt; 옵션을 &lt;code&gt;true&lt;/code&gt;로 설정하면 코드를 아주 엄격하게 검사하게 됩니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2023-08-01 14.44.03.png&quot; data-origin-width=&quot;810&quot; data-origin-height=&quot;178&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ct7uP4/btspxcoOQOO/lo1NOzPcIhIOXugAL5Qdw1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ct7uP4/btspxcoOQOO/lo1NOzPcIhIOXugAL5Qdw1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ct7uP4/btspxcoOQOO/lo1NOzPcIhIOXugAL5Qdw1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fct7uP4%2FbtspxcoOQOO%2Flo1NOzPcIhIOXugAL5Qdw1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;666&quot; height=&quot;146&quot; data-filename=&quot;스크린샷 2023-08-01 14.44.03.png&quot; data-origin-width=&quot;810&quot; data-origin-height=&quot;178&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;&lt;code&gt;strict&lt;/code&gt; 옵션을 설정하지 않았을 때는 &lt;code&gt;hello&lt;/code&gt; 함수의 매개변수의 타입을 지정하지 않아도 오류가 발생하지 않습니다. 하지만 옵션을 &lt;code&gt;true&lt;/code&gt;로 설정하고 나면 아래와 같이 타입 오류를 발생하게 됩니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2023-08-01 14.45.49.png&quot; data-origin-width=&quot;1910&quot; data-origin-height=&quot;310&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/orAkJ/btspmWmM2VT/o44H3KvU5JJryz91af0K0K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/orAkJ/btspmWmM2VT/o44H3KvU5JJryz91af0K0K/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/orAkJ/btspmWmM2VT/o44H3KvU5JJryz91af0K0K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2ForAkJ%2FbtspmWmM2VT%2Fo44H3KvU5JJryz91af0K0K%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;666&quot; height=&quot;108&quot; data-filename=&quot;스크린샷 2023-08-01 14.45.49.png&quot; data-origin-width=&quot;1910&quot; data-origin-height=&quot;310&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;타입스크립트에서는 특별히 매개변수의 타입은 프로그래머가 직접 지정하도록 권장합니다. 왜냐하면 타입스크립트는 함수 매개변수의 타입을 자동 추론할 수 없기 때문에 타입을 프로그래머가 직접 지정하지 않을 경우 엄격한 타입 검사 모드에서는 오류가 발생하게 됩니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;이때 반대로 &lt;code&gt;strict&lt;/code&gt; 를 끄면 엄격하지 않게 타입을 검사하기 때문에 오류가 사라지게 됩니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;ModuleDetection&lt;/span&gt;&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;타입스크립트의 모든 파일은 기본적으로 전역 파일(모듈)로 취급됩니다. 그렇기 때문에 다른 타입스크립트 파일에서 동일한 이름의 변수를 선언하게 되면 오류가 발생하게 됩니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2023-08-01 14.50.14.png&quot; data-origin-width=&quot;1450&quot; data-origin-height=&quot;124&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/kOR6I/btspsGXYmxS/QFv6d2j5mkaB5nfPgv8UKk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/kOR6I/btspsGXYmxS/QFv6d2j5mkaB5nfPgv8UKk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/kOR6I/btspsGXYmxS/QFv6d2j5mkaB5nfPgv8UKk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FkOR6I%2FbtspsGXYmxS%2FQFv6d2j5mkaB5nfPgv8UKk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;666&quot; height=&quot;57&quot; data-filename=&quot;스크린샷 2023-08-01 14.50.14.png&quot; data-origin-width=&quot;1450&quot; data-origin-height=&quot;124&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;이럴 때에는 각 파일에 모듈 시스템 키워드(export, import)를 최소 하나 이상 사용해 해당 파일을 전역 모듈이 아닌 로컬(독립) 모듈로 취급되도록 만들어야 하는데, 이를 자동화 하는 옵션이 바로 &lt;code&gt;moduleDetection&lt;/code&gt; 옵션입니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;다음과 같이 &lt;code&gt;moduleDection&lt;/code&gt; 옵션을 &lt;code&gt;force&lt;/code&gt;로 설정할 경우 자동으로 모든 타입스크립트 파일이 로컬 모듈(독립 모듈)로 취급됩니다.&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;json&quot;&gt;&lt;code&gt;{
  &quot;compilerOptions&quot;: {
    &quot;target&quot;: &quot;ESNext&quot;,
    &quot;module&quot;: &quot;ESNext&quot;,
    &quot;outDir&quot;: &quot;dist&quot;,
        &quot;moduleDetection&quot;: &quot;force&quot;
  },
  &quot;include&quot;: [&quot;src&quot;]
}&lt;/code&gt;&lt;/pre&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&amp;nbsp;&lt;/h3&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;ts-node&lt;/span&gt;&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;&lt;code&gt;moduleDetection&lt;/code&gt; 옵션을 활성화 하고 타입스크립트 파일에서 모듈 시스템을 사용하게 되면 ts-node로 실행할 때 오류가 발생하게 됩니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;이 때 다음과 같이 &lt;code&gt;ts-node&lt;/code&gt;의 옵션을 설정하면 &lt;code&gt;ts-node&lt;/code&gt;로 타입스크립트 모듈을 실행할 수 있게 됩니다.&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;json&quot;&gt;&lt;code&gt;{
  &quot;compilerOptions&quot;: {
    &quot;target&quot;: &quot;ESNext&quot;,
    &quot;module&quot;: &quot;ESNext&quot;,
    &quot;outDir&quot;: &quot;dist&quot;,
        &quot;moduleDetection&quot;: &quot;force&quot;
  },
    &quot;ts-node&quot;: {
        &quot;esm&quot;: true
    },
  &quot;include&quot;: [&quot;src&quot;]
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>TypeScript</category>
      <category>tsconfig.json</category>
      <category>Typescript</category>
      <category>컴파일 옵션</category>
      <category>타입스크립트</category>
      <author>후끈후끈</author>
      <guid isPermaLink="true">https://likelacoste.tistory.com/82</guid>
      <comments>https://likelacoste.tistory.com/82#entry82comment</comments>
      <pubDate>Tue, 1 Aug 2023 15:01:31 +0900</pubDate>
    </item>
    <item>
      <title>Jest axios error (SyntaxError: Cannot use import statement outside a module)</title>
      <link>https://likelacoste.tistory.com/81</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;&lt;b&gt;에러&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2023-07-26 14.48.10.png&quot; data-origin-width=&quot;1416&quot; data-origin-height=&quot;1001&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dEm2Ux/btso6qfyLFF/rPgGIhWHUwIK0KtXblDPTK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dEm2Ux/btso6qfyLFF/rPgGIhWHUwIK0KtXblDPTK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dEm2Ux/btso6qfyLFF/rPgGIhWHUwIK0KtXblDPTK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdEm2Ux%2Fbtso6qfyLFF%2FrPgGIhWHUwIK0KtXblDPTK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;666&quot; height=&quot;471&quot; data-filename=&quot;스크린샷 2023-07-26 14.48.10.png&quot; data-origin-width=&quot;1416&quot; data-origin-height=&quot;1001&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;테스트 코드를 실행하면서 에러를 마주하게 되었다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2023-07-26 14.52.20.png&quot; data-origin-width=&quot;1401&quot; data-origin-height=&quot;567&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/EsPCA/btso4yrL4eE/DlasPPmBLJ045jpd3lmVfk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/EsPCA/btso4yrL4eE/DlasPPmBLJ045jpd3lmVfk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/EsPCA/btso4yrL4eE/DlasPPmBLJ045jpd3lmVfk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FEsPCA%2Fbtso4yrL4eE%2FDlasPPmBLJ045jpd3lmVfk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;666&quot; height=&quot;270&quot; data-filename=&quot;스크린샷 2023-07-26 14.52.20.png&quot; data-origin-width=&quot;1401&quot; data-origin-height=&quot;567&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;에러창에서 공식 문서를 안내하고 있어서 공식 문서에서 나온 내용대로 여러 시도를 해봤지만 해결되지 않았다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;&lt;code&gt;jest.config.js&lt;/code&gt;와 &lt;code&gt;babel.config.js&lt;/code&gt;를 가지고 이런저런 설정을 해보기도 하고, 여러 라이브러리를 설치하며 컴파일 관련 설정을 만져보았지만 에러가 해결되지 않았다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;그러다가 stackoverflow에서 해결 방법을 찾다가 간단한 해결책을 발견하게 되었다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2023-07-26 14.58.14.png&quot; data-origin-width=&quot;1512&quot; data-origin-height=&quot;678&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dgsY8S/btso0slt3LB/yeoPk2HkJd5l039IacnbUK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dgsY8S/btso0slt3LB/yeoPk2HkJd5l039IacnbUK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dgsY8S/btso0slt3LB/yeoPk2HkJd5l039IacnbUK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdgsY8S%2Fbtso0slt3LB%2FyeoPk2HkJd5l039IacnbUK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;666&quot; height=&quot;299&quot; data-filename=&quot;스크린샷 2023-07-26 14.58.14.png&quot; data-origin-width=&quot;1512&quot; data-origin-height=&quot;678&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;&lt;b&gt;해결&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;pre class=&quot;1c&quot;&gt;&lt;code&gt;  &quot;scripts&quot;: {
    //..configs
    &quot;test&quot;: &quot;react-scripts test --transformIgnorePatterns \&quot;node_modules/(?!axios)/\&quot;&quot;,
  },&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;&lt;code&gt;package.json&lt;/code&gt;에서 &lt;code&gt;scripts&lt;/code&gt;를 위와 같이 변경해주었다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;그리고 난 후 &lt;code&gt;npm run test&lt;/code&gt;를 실행하면?&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2023-07-26 15.04.15.png&quot; data-origin-width=&quot;637&quot; data-origin-height=&quot;325&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cpJTtC/btsoZoKBz8w/G8oyoI4YyV6uOHTpHkh9J1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cpJTtC/btsoZoKBz8w/G8oyoI4YyV6uOHTpHkh9J1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cpJTtC/btsoZoKBz8w/G8oyoI4YyV6uOHTpHkh9J1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcpJTtC%2FbtsoZoKBz8w%2FG8oyoI4YyV6uOHTpHkh9J1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;637&quot; height=&quot;325&quot; data-filename=&quot;스크린샷 2023-07-26 15.04.15.png&quot; data-origin-width=&quot;637&quot; data-origin-height=&quot;325&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;태스트가 성공적으로 실행되었다 ㅠㅠ&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>개발이야기/Error</category>
      <category>Error</category>
      <category>jest</category>
      <category>에러</category>
      <category>테스트</category>
      <author>후끈후끈</author>
      <guid isPermaLink="true">https://likelacoste.tistory.com/81</guid>
      <comments>https://likelacoste.tistory.com/81#entry81comment</comments>
      <pubDate>Wed, 26 Jul 2023 15:11:47 +0900</pubDate>
    </item>
    <item>
      <title>렌더링??</title>
      <link>https://likelacoste.tistory.com/80</link>
      <description>&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;렌더링이란&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;리액트에서 렌더링이란&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;u&gt;화면에 특정한 요소를 그려내는 것을 의미&lt;/u&gt;합니다. 이 렌더링 과정을 잘 처리해주는 것이 우리가 Vanila JavaScript를 사용하지 않고 React와 같은 UI라이브러리를 사용하는 이유입니다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;브라우저에서 렌더링이란 DOM요소를 계산하고 화면에 그려내는 것을 의미합니다. HTML과 CSS를 가지고 만들어진 DOM과 CSSOM은 서로 결합되어 브라우저에 그려집니다. 그리고 브라우저에서 제공하는 DOM API를 JavaScript를 통해 호출하면서 브라우저에 그려진 화면을 변화시키게 됩니다. 하지만 JavaScript를 이용해서 DOM을 직접 접근하고 수정, 최적화 하는 것은 애플리케이션의 규모가 커질 수록 관리하기가 힘들어집니다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;React는 렌더링 과정을 대신 처리해주고, 개발자는 UI를 설계하는 것이 집중할 수 있도록 해줍니다. 하지만 React 내부에서 처리해주는 렌더링을 최적화 해야 되는 상황이 발생하기도 하는데, 렌더링 과정을 최적화 해주기 위해서는 React 내부에서 렌더링이 언제 발생하고, 어떤 과정을 거쳐서 이루어지는지를 이해하고 있어야 각 과정에서 렌더링을 최적화 할 수 있습니다.&lt;/span&gt;&lt;/p&gt;
&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;&amp;nbsp;&lt;/h2&gt;
&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;리렌더링은 언제 발생할까?&lt;/span&gt;&lt;/b&gt;&lt;/h2&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;리액트에서 리렌더링이 되는 시점에 대해 알아보기 전에, 리액트에서 state(상태)이 무엇이고 왜 사용하는지에 대해 알아야 합니다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;리액트에서&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;state(상태)&lt;/b&gt;이란 컴포넌트 내부에서 변할 수 있는 값을 말하는데, UI와 상태(state)를 연동시키기 위해서 사용됩니다. UI와 연동되어야 하고, 변할 여지가 있는 데이터들을 state이라는 형태로 사용하여, 데이터가 변경되었을 때 UI가 그에 맞춰서 변화하기 위해서 state을 변경시키고, state이 변경될 때마다 리렌더링이 됩니다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;즉, 리렌더링이 되기 위해서는 리액트에서 상태(state)가 변경되었다는 것을 알아야 합니다. 리액트가 상태(state)가 변경되었다는 것을 알기 위해서는 setState을 사용해야 합니다. 만약 setState을 사용하지 않고 state을 직접 변경하게 되면 리액트에서 상태(state)가 변경되었다는 것을 인지하지 못할 수도 있어서 리렌더링이 발생하지 않을 수 있습니다.(setState을 사용하는 이유)&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;특정 컴포넌트의 state이 변한다면, 해당 컴포넌트와 해당 컴포넌트의 하위에 있는 모든 컴포넌트는 리렌더링이 발생하게 됩니다. 이는 리액트를 이용해서 애플리케이션을 설계하고, 최적화하는데 가장 기본이 되는 사항입니다.&lt;/span&gt;&lt;/p&gt;
&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;&amp;nbsp;&lt;/h2&gt;
&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;리액트의 렌더링 과정&lt;/span&gt;&lt;/b&gt;&lt;/h2&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;앞서, 리액트는 state가 변화했을 때 리렌더링을 발생시킨다고 했습니다. state(상태)이 변화되고 최종적으로 브라우저상의 UI에 반영되기까지 각 컴포넌트에서는 크게 아래의 4단계를 거치게 됩니다.&lt;/span&gt;&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal; color: #333333; text-align: start;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;기존 컴포넌트의 UI를 재사용할 지 확인한다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;함수 컴포넌트: 컴포넌트 함수를 호출한다 / Class 컴포넌트:&lt;span&gt;&amp;nbsp;&lt;/span&gt;render&lt;span&gt;&amp;nbsp;&lt;/span&gt;메소드를 호출한다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;2의 결과를 통해서 새로운 VirtualDOM을 생성한다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;이전의 VirtualDOM과 새로운 VirtualDOM을 비교해서 실제 변경된 부분만 DOM에 적용한다.&lt;/span&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;VirtualDOM을 왜 사용하는가?&lt;/span&gt;&lt;/b&gt;&lt;/h3&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;VirtualDOM은 리액트가 수행하는 최적화 입니다. 리액트에서 VirtualDOM을 사용하는 이유에 대해서 알아보도록 하겠습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;먼저 브라우저는 근본적으로 화면을 보여주기 위해서 HTML, CSS, JavaScript를 다운로드 받고 그를 처리해서 화면에 픽셀 형태로 그려냅니다. 그리고 이 과정을 CRP(Critical Rendering Path)라고 부릅니다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;브라우저 렌더링 과정(CRP)는 기본적으로 아래의 과정을 수행합니다.&lt;/span&gt;&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal; color: #333333; text-align: start;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;HTML을 파싱해서 DOM을 만든다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;CSS를 파싱해서 CSSOM을 만든다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;DOM과 CSSOM을 결합해서 Render Tree를 만든다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;Render Tree와 Viewport의 width를 통해서 각 요소들의 위치와 크기를 계산한다.&lt;b&gt;(Layout)&lt;/b&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;지금까지 계산된 정보를 이용해 Render Tree상의 요소들을 실제 Pixel로 그려낸다.&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;b&gt;(Paint)&lt;/b&gt;&lt;/span&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;렌더링 이후에 DOM 또는 CSSOM이 수정될 때 마다 또는 UI를 변화하기 위해 DOM을 조작할 때마다 CRP가 수행됩니다. 이는 브라우저에게 많은 연산을 요구하게 되어 퍼포먼스를 저하시키는 요인이 될 수 있습니다. 리액트에서는 CRP가 수행되는 횟수를 최적화 하기 위해서 VirtualDOM을 사용합니다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;리액트에서는 UI의 변화가 발생하면 변화에 필요한 DOM조작을 바로 실제 DOM에 적용하는 것이 아니라, 리액트에서 관리하는 VirtualDOM(DOM과 유사한 객체형태)을 만들어 냅니다. 그리고 이전의 VirtualDOM과 새로운 VirtualDOM을 비교해서 실제로 변화가 필요한 DOM 요소를 찾아내어, 한번에 해당 DOM 요소를 조작합니다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;이러한 과정을 통해서 브라우저에서 수행되는 CRP의 빈도를 줄일 수 있습니다.(이는 리액트가 수행하는 최적화입니다.)&lt;/span&gt;&lt;/p&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&amp;nbsp;&lt;/h3&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;내가 할 수 있는 최적화?&lt;/span&gt;&lt;/b&gt;&lt;/h3&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;VirtualDOM을 통한 최적화는 리액트 내부적으로 수행하기 때문에 개발자 입장에서 따로 최적화를 수행할 필요가 없습니다. 그렇다면 리액트를 사용하는 개발자가 할 수 있는 최적화는 무엇이 있을까?&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;먼저 부모 컴포넌트가 렌더링 되면서 자식 컴포넌트가 렌더링되지 않고 재사용할지를 확인해야 합니다. 리렌더링 될 컴포넌트의 UI가 이전의 UI와 동일하다고 판단되는 경우 새롭게 컴포넌트를 호출하지 않고 이전의 UI를 그대로 사용하도록 함으로서 최적화를 수행할 수 있습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;다음으로는 컴포넌트 함수가 호출되면서 만들어질 VirtualDOM의 형태를 이전의 VirtualDOM과 차이가 적은 형태로 만들어지도록 하는 것입니다. 예를들어 UI를 바꾸기 위해서&lt;span&gt;&amp;nbsp;&lt;/span&gt;&amp;lt;div&amp;gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;태그를&lt;span&gt;&amp;nbsp;&lt;/span&gt;&amp;lt;span&amp;gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;태그로 변환시키는 것보다&lt;span&gt;&amp;nbsp;&lt;/span&gt;&amp;lt;div className=&quot;block&quot; /&amp;gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;을&lt;span&gt;&amp;nbsp;&lt;/span&gt;&amp;lt;div className=&quot;inline&quot;&amp;gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;으로 변환시키는 것이 VirtualDOM끼리 비교했을 때 차이가 적은 것을 볼 수 있습니다.&lt;/span&gt;&lt;/p&gt;
&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;&amp;nbsp;&lt;/h2&gt;
&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;결론&lt;/span&gt;&lt;/b&gt;&lt;/h2&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;내가 리액트에서 제공하는&lt;span&gt;&amp;nbsp;&lt;/span&gt;useSate&lt;span&gt;&amp;nbsp;&lt;/span&gt;을 사용하고 있으면서 컴포넌트의 렌더링 과정을 모르거나 또는 렌더링 과정을 고려하지 않고 useState을 사용하고 있다면 반성해야한다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;useState&lt;span&gt;&amp;nbsp;&lt;/span&gt;은 단순히 변수를 선언하고 값을 유동적으로 변경해주는 것으로 끝이 아니라 컴포넌트를 다시 렌더링을 시키는 열쇠이다. 그렇기 때문에 아무런 생각 없이&lt;span&gt;&amp;nbsp;&lt;/span&gt;useState&lt;span&gt;&amp;nbsp;&lt;/span&gt;을 마구잡이로 사용하게 되면 생각지 못한 렌더링이 발생되어 내가 원하는데로 작동되지 않을 수 있다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;반대로&lt;span&gt;&amp;nbsp;&lt;/span&gt;useState&lt;span&gt;&amp;nbsp;&lt;/span&gt;을 잘 활용한다면 그만큼 사용자로 하여금 애플리케이션과 원활한 상호작용을 할 수 있도록 만들 수 있다. 뿐만 아니라 내가 작성하는 코드의 질과 유지보수성을 높일 수 있다.&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style=&quot;color: #333333; text-align: start;&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>React</category>
      <category>React</category>
      <category>rendering</category>
      <category>렌더링</category>
      <category>리액트</category>
      <category>최적화</category>
      <author>후끈후끈</author>
      <guid isPermaLink="true">https://likelacoste.tistory.com/80</guid>
      <comments>https://likelacoste.tistory.com/80#entry80comment</comments>
      <pubDate>Fri, 7 Jul 2023 18:26:46 +0900</pubDate>
    </item>
    <item>
      <title>[프리온보딩 프론트엔드 인턴십] 1주차</title>
      <link>https://likelacoste.tistory.com/79</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;프리온보딩 프론트엔드 인턴십 1주차, 이전에 진행한 과제를 가지고 Best Practice을 찾기 위해 서로 의견을 나누는 시간을 가졌다. 동일한 내용의 과제였지만, 구현된 코드는 서로 너무나도 다른 것을 보며&lt;b&gt; &amp;lsquo;코드를 작성할 때 정답은 없다.&amp;rsquo;&lt;/b&gt; 라는 말을 다시한번 생각하게 되었다.&lt;/span&gt;&lt;/p&gt;
&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;&amp;nbsp;&lt;/h2&gt;
&lt;h2 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;라우팅과 리다이랙션&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;진행한 과제에서 내가 맡아서 생각해본 부분은 페이지 라우팅과 리다이랙션이다. 이전에는 과제를 제출하기에 바빠서 이 부분을 크게 신경쓰지 못했지만, 과제를 진행하면서 조금 더 코트의 양을 줄이면서 간소화할 수 있겠다는 생각을 했던 부분이기 때문에 시작하기 전에 기대가 되었다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;라우팅 정보 리스트화&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;과제 안에서 페이지의 수는 3개(로그인, 회원가입, TODO)였다. 페이지의 수가 작기 때문에, 라우팅 로직의 코드를 하나하나 하드코딩을 해서 구현할 수 있기 때문에 어렵지 않다는 생각을 하였다. 하지만 페이지의 숫자가 많아진다면 코드를 관리하기 어려울 것이라는 생각을 하게 되었고, 코드를 간소화 하는 방법을 찾아보게 되었다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;페이지와 레이어를 리스트 형태로 만들어 각 경로에 맞는 컴포넌트를 팹핑하여, 해당 리스트를 렌더링하는 형태로 코드를 작성하면 보다 코드를 간소화할 수 있을 것 같다는 생각이 들어 이대로 진행해보기로 하였다.&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;xquery&quot;&gt;&lt;code&gt;const routerData = [
  {
    id: 0,
    path: '/',
    element: &amp;lt;Home /&amp;gt;,
  },
  {
    id: 1,
    path: '/signin',
    element: &amp;lt;Signin /&amp;gt;,
  },
  {
    id: 2,
    path: '/signup',
    element: &amp;lt;Signup /&amp;gt;,
  },
  {
    id: 3,
    path: '/todo',
    element: &amp;lt;Todo /&amp;gt;,
  },
];
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;먼저 위 코드를 보면 라우팅에 필요한 정보들을 리스트화였다. 그런 후에 &lt;code&gt;createBrowserRouter&lt;/code&gt;를 사용하여 라우팅 리스트를 렌더링 하였다.&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;xquery&quot;&gt;&lt;code&gt;export const routers = createBrowserRouter(
  routerData.map(router =&amp;gt; {
     return {
       path: router.path,
       element: router.element,
     };
  })
);&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;이전에 하나하나 작성한 코드보다 기능적인 변화는 크게 없지만, 라우팅의 정보를 한 눈에 볼 수 있으면서 코드의 구조를 명확하게 알 수 있었다.&lt;/span&gt;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&amp;nbsp;&lt;/h3&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;라우트 기반 페이지 분할&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;이전에 각 페이지 컴포넌트 안에서 리다이렉션 조건에 맞게 이동하도록 코드를 작성하였다. 코드를 작성할 당시에 비슷한 기능을 하는 코드가 반복되어 사용되는 것이 불필요하다는 생각이 들었고, 해당 문제를 해결할 방법을 고민해보기로 했다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;리다이렉션 조건&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;1. 로그인을 진행한 후, 토큰을 발급받은 상태에서 로그인 및 회원가입 페이지에 접근하면 todo 페이지로 이동&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;span style=&quot;color: #333333; text-align: left;&quot;&gt;2. 토큰이 없는 상태에서&amp;nbsp;&lt;/span&gt;todo&lt;span style=&quot;color: #333333; text-align: left;&quot;&gt;&amp;nbsp;페이지로 접근하면 로그인 페이지로 이동&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;구현해야하는 조건을 보면, 페이지를 토큰이 필요한 페이지와 토큰이 필요하지 않은 페이지로 구분할 수 있다는 것을 볼 수 있다. 따라서 토큰의 여부에 따라 페이지를 분리하여 각각의 페이지에 맞게 리다이렉션을 구현하면 어떨까 라는 생각을 하게 되었다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;먼저 라우팅 정보에 토큰이 필요한지 여부에 대한 정보를 넣어 작성하였다.&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot;&gt;&lt;code&gt;const routerData = [
  {
    id: 0,
    path: '/',
    element: &amp;lt;Home /&amp;gt;,
    withAuth: false,
  },
  {
    id: 1,
    path: '/signin',
    element: &amp;lt;Signin /&amp;gt;,
    withAuth: false,
  },
  {
    id: 2,
    path: '/signup',
    element: &amp;lt;Signup /&amp;gt;,
    withAuth: false,
  },
  {
    id: 3,
    path: '/todo',
    element: &amp;lt;Todo /&amp;gt;,
    withAuth: true,
  },
];&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;다음으로 컴포넌트들을 맵핑할 때, 토큰 여부에 따라 분리하여 토큰이 필요한 페이지에는 리다이렉션을 진행하는 컴포넌트인 &lt;code&gt;GeneralLayout&lt;/code&gt;으로 감싸고, 토큰이 필요하지 않는 페이지는 그냥 반환되도록 하였다.&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;xquery&quot;&gt;&lt;code&gt;export const routers = createBrowserRouter(
  routerData.map(router =&amp;gt; {
    if (router.withAuth) {
      return {
        path: router.path,
        element: &amp;lt;GeneralLayout&amp;gt;{router.element}&amp;lt;/GeneralLayout&amp;gt;,
      };
    } else {
      return {
        path: router.path,
        element: router.element,
      };
    }
  })
);&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;비록 진행하는 과제에서는 토큰이 필요한 페이지가 todo 페이지 하나이기 때문에 위와 같이 코드를 작성해도 크게 차이를 느낄 수 없지만, 페이지의 수가 많으면 많을 수록 반복해서 작성해야하는 코드의 양을 줄일 수 있습니다. (로그인과 회원가입 페이지를 따로 분리하기 어렵다고 판단하여 해당 페이지에서의 리다이렉션은 페이지 컴포넌트 안에서 진행하였다.)&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;리다이랙션&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;이전에는 조건문을 사용하여 페이지마다 리다이랙션을 진행하였다. 동일한 기능을 하는 코드를 함수화하여 재사용할 수 있도록 만들면 더 간결하고 깨끗한 코드 작성을 할 수 있다는 생각을 하였고, 리다이랙션 조건에 따라 페이지를 이동하는 기능을 가지고 있는 custom Hook을 만들어 보게 되었다.&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;typescript&quot;&gt;&lt;code&gt;interface useAuthRedirectionProps {
  path: PATH;
  isRedirectionIfAuth: boolean;
}

const useAuthRedirection = ({
  path,
  isRedirectionIfAuth,
}: useAuthRedirectionProps) =&amp;gt; {
  const [isAuth, setIsAuth] = useState&amp;lt;boolean&amp;gt;(!!getLocalStorageToken());

  const { replaceTo } = useRouter();

  useEffect(() =&amp;gt; {
    if (getLocalStorageToken()) {
      setIsAuth(true);
      if (isRedirectionIfAuth) {
        replaceTo(path);
      }
      return;
    }
    setIsAuth(false);
    if (!isRedirectionIfAuth) {
      replaceTo(path);
    }
  }, [isRedirectionIfAuth, replaceTo, path]);
  return isAuth;
};

export default useAuthRedirection;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;code&gt;useAuthRedirection&lt;/code&gt; 함수는 매개변수로 이동해야하는 경로와 리다이렉션이 발생될 때의 조건을 &lt;code&gt;boolean&lt;/code&gt; 값으로 받는다. 조건에 맞게 리다이렉션을 진행하고, 토큰의 여부를 &lt;code&gt;boolean&lt;/code&gt; 값으로 반환하게 된다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;이전에 토큰이 필요한 페이지를 감쌌던 &lt;code&gt;GeneralLayout&lt;/code&gt; 컴포넌트 안에서 리다이렉트처리를 하게 되면, &lt;code&gt;GeneralLayout&lt;/code&gt; 컴포넌트의 자식으로 들어가게 되는 컴포넌트들은 &lt;code&gt;useAuthRedirection&lt;/code&gt; 함수가 실행되어 조건에 맞게 페이지를 리다이렉션하게 된다.&lt;/span&gt;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&amp;nbsp;&lt;/h2&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;후기&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;만들어본 과제를 다시한번 뜯어 보면서 코드리뷰의 필요성과 중요성에 대해 알게되었다. 코드를 다시 들여다보고 개선해야할 점을 찾는 과정 속에서 생각하지 못했던 부분이나 쉽게 놓쳤던 부분에 대해 생각해보는 시간을 갖을 수 있었고, 개선하는 과정에서 해당 부분을 깊게 공부해 볼 수 있었다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;그리고 내가 작성한 코드만 보며 생각하는게 아니라 팀원들의 코드를 함께 보면서, 코드를 더 효율적이고 직관적으로 작성하는 것에 대해 고민해 볼 수 있어서 좋았다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>개발이야기/원티드</category>
      <category>Wanted</category>
      <category>원티드</category>
      <category>프리온보딩</category>
      <category>프리온보딩 프론트엔드 인턴십</category>
      <author>후끈후끈</author>
      <guid isPermaLink="true">https://likelacoste.tistory.com/79</guid>
      <comments>https://likelacoste.tistory.com/79#entry79comment</comments>
      <pubDate>Mon, 3 Jul 2023 01:10:23 +0900</pubDate>
    </item>
    <item>
      <title>[프리온보딩 프론트엔드 인턴십] 선발과제</title>
      <link>https://likelacoste.tistory.com/78</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;  &lt;b&gt;설치한 패키지&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;- react, react-router-dom&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;- axios&lt;/span&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;  &lt;b&gt;프로젝트 구조&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt; &amp;nbsp;src&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;├──   apis : API 호출과 관련된 함수 모음&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;├──   components : Page에서 사용되는 컴포넌트 모음&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;├──   helper : 재사용되는 함수 모음&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;├──   hooks : Custom Hook&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;├──   pages : 페이지 컴포넌트&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;└──   styles : CSS 모음&lt;/span&gt;&lt;/blockquote&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li style=&quot;list-style-type: none;&quot;&gt;&amp;nbsp;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&amp;nbsp;&lt;/h2&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;1. 이메일, 비밀번호 유효성 검사&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;이메일 조건: @ 포함&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;비밀번호 조건: 8자 이상&lt;/span&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;로그인과 회원가입 간에 변경되는 데이터를 받아 주어진 조건에 맞게 유효성을 검사하는 함수를 만들어 검사한다.&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot;&gt;&lt;code&gt;// helper/validationCheck.js

export const checkEmail = (email) =&amp;gt; {
  return email.indexOf(&quot;@&quot;) === -1 ? &quot;fail&quot; : &quot;success&quot;;
};

export const checkPassword = (password) =&amp;gt; {
  return password.length &amp;lt; 8 ? &quot;fail&quot; : &quot;success&quot;;
};&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;결과에 따라 &lt;code&gt;fail&lt;/code&gt; 과 &lt;code&gt;success&lt;/code&gt; 를 반환하고 유효성 검사를 통과 여부에 따라 &lt;code&gt;button&lt;/code&gt;의 활성화 여부가 변경된다.&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;html xml&quot; data-ke-language=&quot;html&quot;&gt;&lt;code&gt;// /pages/Login.jsx

&amp;lt;button
    type=&quot;submit&quot;
    className=&quot;member-wrapper-button&quot;
    disabled={
        checkEmail(email) === &quot;success&quot; &amp;amp;&amp;amp;
        checkPassword(password) === &quot;success&quot;
                ? &quot;&quot;
                : &quot;disabled&quot;
            }
    data-testid=&quot;signin-button&quot;
&amp;gt;
    로그인
&amp;lt;/button&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&amp;nbsp;&lt;/h2&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;2. 회원가입 완료 시 &lt;code&gt;/signin&lt;/code&gt; 이동&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;회원가입 API 호출 후, 응답의 상태 코드가 200인 경우에 로그인 페이지로 이동한다. (회원가입이 완료되지 못하고 에러가 발생하는 경우, 사용자에게 에러 메시지를 &lt;code&gt;alert&lt;/code&gt;)&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot;&gt;&lt;code&gt;// /pages/Signup.jsx

const signupSubmitHandler = async (event) =&amp;gt; {
    event.preventDefault();

    const userInfo = { email, password };

    try {
      const response = await signup_API(userInfo);

      if (response.status === 201) {
        routeTo(&quot;/signin&quot;);
      }
    } catch (error) {
      const { response } = error;
      alert(response.data?.message);
    }
  };&lt;/code&gt;&lt;/pre&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;code&gt;routeTo&lt;/code&gt; 함수는 페이지를 이동하는 함수&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;3. 로그인 완료 시 &lt;code&gt;/todo&lt;/code&gt; 이동&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;로그인 버튼을 클릭하면 아래의 &lt;code&gt;loginSubmitHandler&lt;/code&gt; 함수가 실행한다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;함수가 실행되면 로그인 API 호출(&lt;code&gt;signin_API&lt;/code&gt;) 후, 응답의 상태 코드가 200인 경우에 발급받은 토큰을 &lt;code&gt;localStorage&lt;/code&gt;에 저장하고 &lt;code&gt;/todo&lt;/code&gt; 로 이동된다.&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot;&gt;&lt;code&gt;// /pages/Login.jsx

const loginSubmitHandler = async (event) =&amp;gt; {
    event.preventDefault();

    const userInfo = { email, password };
    try {
      const response = await signin_API(userInfo);
      if (response.status === 200) {
        setLocalStorage(response.data);
        routeTo(&quot;/todo&quot;);
      }
    } catch (error) {
      console.log(error);
    }
  };&lt;/code&gt;&lt;/pre&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;code&gt;setLocalStorage&lt;/code&gt; 함수는 &lt;code&gt;localStorage&lt;/code&gt;에 토큰을 저장&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;4. 로그인 여부에 따른 리다이렉트 구현&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;각 페이지에서 useEffect를 사용하여 localStorage에 토큰의 여부에 따라 리다이렉트 된다.&lt;/span&gt;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;이 방법은 별로 좋지 않은 방법이라고 생각된다. 페이지마다 코드를 반복하지 않고 구현할 수 있는 방법을 생각하면 좋을 것 같다.&lt;/span&gt;&lt;/blockquote&gt;
&lt;pre class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot;&gt;&lt;code&gt;// /pages/Login.jsx

useEffect(() =&amp;gt; {
    if (!!getLocalStorage(&quot;token&quot;)) {
      routeTo(&quot;/todo&quot;);
    }
  }, []);

// /pages/Todo.jsx
useEffect(() =&amp;gt; {
    if (!getLocalStorage(&quot;token&quot;)) {
      return routeTo(&quot;/signin&quot;);
    }
        ....
,[]);&lt;/code&gt;&lt;/pre&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&amp;nbsp;&lt;/h2&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;5. &lt;code&gt;/todo&lt;/code&gt; 에서 TODO 리스트 목록 표시&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;각각의 TODO를 나타내는 &lt;code&gt;TodoItems&lt;/code&gt; 컴포넌트를 분리하여 만들었다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;code&gt;useEffect&lt;/code&gt;를 사용하여 &lt;code&gt;/todo&lt;/code&gt; 페이지가 처음 마운트 되었을 때, TODO 리스트를 불러오는 &lt;code&gt;getTodo_API&lt;/code&gt; 함수를 실행한다.&amp;nbsp; 응답 상태코드가 200인 경우, 서버로부터 받은 리스트를 상태 값으로 저장한다.&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot;&gt;&lt;code&gt;// /pages/Todo.jsx

useEffect(() =&amp;gt; {
    if (!getLocalStorage(&quot;token&quot;)) {
      return routeTo(&quot;/signin&quot;);
    }

    const getMyTodo = async () =&amp;gt; {
      try {
        const response = await getTodo_API();
        if (response.status === 200) {
          setTodoLit(response.data);
        }
      } catch (error) {
        console.log(error);
      }
    };

    getMyTodo();
  }, []);&lt;/code&gt;&lt;/pre&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&amp;nbsp;&lt;/h2&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;6. TODO 추가&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;작성한 TODO를 추가하는 버튼을 클릭하면 &lt;code&gt;onSubmitHandler&lt;/code&gt; 함수를 실행한다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;함수가 실행되면 작성된 TODO를 객체로 담아서 &lt;code&gt;createTodo_API&lt;/code&gt; 함수를 실행하고, API 호출 후에 응답 상태코드가 201인 경우, 이전에 저장되어 있던 리스트 상태값의 가장 아래에 새로 저장된 TODO를 추가한 뒤 입력 창을 비워준다.&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot;&gt;&lt;code&gt;// /pages/Todo.jsx

const onSubmitHandler = async (event) =&amp;gt; {
    event.preventDefault();

    const newTodo = {
      todo: writeTodo,
    };

    try {
      const response = await createTodo_API(newTodo);

      if (response.status === 201) {
        setTodoLit([...todoList, response.data]);
        setWriteTodo(&quot;&quot;);
      }
    } catch (error) {
      console.log(error);
    }
  };&lt;/code&gt;&lt;/pre&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&amp;nbsp;&lt;/h2&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;7. chekbox로 완료 여부 수정&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;code&gt;onCompletHandler&lt;/code&gt; 함수는 체크박스 변경과 update API(&lt;code&gt;updateTodo_API&lt;/code&gt;)를 호출한다.&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;javascript&quot;&gt;&lt;code&gt;// /components/TodoItems.jsx

const onCompletHandler = async () =&amp;gt; {
    const body = { todo: chageTodo, isCompleted: !isChecked };
    try {
      const response = await updateTodo_API(id, body);
      if (response.status === 200) {
        setIsChecked((prev) =&amp;gt; !prev);
      }
    } catch (error) {
      console.log(error);
    }
  };&lt;/code&gt;&lt;/pre&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&amp;nbsp;&lt;/h2&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;8. TODO 수정 및 삭제 버튼&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;pre class=&quot;dust&quot;&gt;&lt;code&gt;// /components/TodoItems.jsx

&amp;lt;li&amp;gt;
  &amp;lt;label&amp;gt;
    &amp;lt;input
      className=&quot;m-r todo-todoList-check&quot;
      type=&quot;checkbox&quot;
      onChange={onCompletHandler}
      checked={isChecked ? &quot;checked&quot; : &quot;&quot;}
    /&amp;gt;
    &amp;lt;span&amp;gt;{chageTodo}&amp;lt;/span&amp;gt;
  &amp;lt;/label&amp;gt;
  &amp;lt;div&amp;gt;
    &amp;lt;button
      className=&quot;todo-todoList-button&quot;
      data-testid=&quot;modify-button&quot;
      onClick={onModifyHandler}
    &amp;gt;
      수정
    &amp;lt;/button&amp;gt;
    &amp;lt;button
      className=&quot;m-l todo-todoList-button&quot;
      data-testid=&quot;delete-button&quot;
      onClick={() =&amp;gt; onDeleteHandler(id)}
    &amp;gt;
      삭제
    &amp;lt;/button&amp;gt;
  &amp;lt;/div&amp;gt;
&amp;lt;/li&amp;gt;;&lt;/code&gt;&lt;/pre&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&amp;nbsp;&lt;/h2&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;9. TODO 삭제&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;삭제 버튼을 클릭하면 &lt;code&gt;onDeleteHandler&lt;/code&gt; 함수가 실행된다. 함수가 실행되면 해당 아이템을 지우는 API(&lt;code&gt;deleteTodo_API&lt;/code&gt;)를 호출하고, 응답 상태코드가 204인 경우, 리스트를 담고 있는 상태 값(배열)을 &lt;code&gt;filter&lt;/code&gt; 매서드를 사용하여 해당 TODO 아이템을 제거한다.&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;javascript&quot;&gt;&lt;code&gt;// /pages/Todo.jsx

const onDeleteHandler = useCallback(async (id) =&amp;gt; {
    try {
      const response = await deleteTodo_API(id);
      if (response.status === 204) {
        setTodoLit((prev) =&amp;gt; [...prev].filter((todo) =&amp;gt; todo.id !== id));
      }
    } catch (error) {
      console.log(error);
    }
  }, []);&lt;/code&gt;&lt;/pre&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&amp;nbsp;&lt;/h2&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;10. TODO 수정&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;code&gt;isModify&lt;/code&gt; 상태 값에 따라 수정모드가 활성화 여부가 변경된다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;TODO를 수정한 후에 수정 버튼을 클릭하면 &lt;code&gt;onSubmitHandler&lt;/code&gt; 함수가 실행되어 수정 API(&lt;code&gt;updateTodo_API&lt;/code&gt;)를 호출한다. 호출 결과 응답 상태코드가 200인 경우, &lt;code&gt;isModify&lt;/code&gt; 상태 값을 변경하여 수정 모드를 비활성화 한다.&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot;&gt;&lt;code&gt;// /components/TodoItems.jsx

const onModifyHandler = () =&amp;gt; {
    setIsModify((prev) =&amp;gt; !prev);
  };

  const onSubmitHandler = async () =&amp;gt; {
    const body = { todo: chageTodo, isCompleted: isChecked };
    try {
      const response = await updateTodo_API(id, body);
      if (response.status === 200) {
        onModifyHandler();
      }
    } catch (error) {
      console.log(error);
    }
  };&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;a href=&quot;https://github.com/lIIIlIIIlIIIl/wanted-pre-onboarding-frontend&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://github.com/lIIIlIIIlIIIl/wanted-pre-onboarding-frontend&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1687931746501&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;object&quot; data-og-title=&quot;GitHub - lIIIlIIIlIIIl/wanted-pre-onboarding-frontend&quot; data-og-description=&quot;Contribute to lIIIlIIIlIIIl/wanted-pre-onboarding-frontend development by creating an account on GitHub.&quot; data-og-host=&quot;github.com&quot; data-og-source-url=&quot;https://github.com/lIIIlIIIlIIIl/wanted-pre-onboarding-frontend&quot; data-og-url=&quot;https://github.com/lIIIlIIIlIIIl/wanted-pre-onboarding-frontend&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/bhS0He/hyS8oAmNGe/6Xb5Y6whEbd1oPdLXYKsZk/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600&quot;&gt;&lt;a href=&quot;https://github.com/lIIIlIIIlIIIl/wanted-pre-onboarding-frontend&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://github.com/lIIIlIIIlIIIl/wanted-pre-onboarding-frontend&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/bhS0He/hyS8oAmNGe/6Xb5Y6whEbd1oPdLXYKsZk/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;GitHub - lIIIlIIIlIIIl/wanted-pre-onboarding-frontend&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Contribute to lIIIlIIIlIIIl/wanted-pre-onboarding-frontend development by creating an account on GitHub.&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;github.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>개발이야기/원티드</category>
      <category>Wanted</category>
      <category>원티드</category>
      <category>프리온보딩 프론트엔드 인턴십</category>
      <author>후끈후끈</author>
      <guid isPermaLink="true">https://likelacoste.tistory.com/78</guid>
      <comments>https://likelacoste.tistory.com/78#entry78comment</comments>
      <pubDate>Wed, 28 Jun 2023 14:59:32 +0900</pubDate>
    </item>
    <item>
      <title>Default Value</title>
      <link>https://likelacoste.tistory.com/77</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;자바스크립트에서 함수를 안전하게 사용하기 위한 방법 중 하나는 함수의 매개변수의 기본값을 넣어주는 것이다. 매개변수에 기본값을 넣어주면 함수의 인자에 값이 넘어오지 않아도 함수를 실행하는데 오류가 발생하지 않는다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre class=&quot;pgsql&quot;&gt;&lt;code&gt;function exampleFuc(options){
    options = options || {};
    const margin = options.margin || 0;
    const padding = options.padding || 0;
    const center = options.center || false;

    return {
        margin,
        padding,
        center,
    };
}

console.log(exampleFuc()); // {margin: 0, padding: 0, center: false}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위의 함수는 함수 내부에서 || 연산자를 사용하여 지역변수의 재정하는 방식으로 기본값을 설정한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;code&gt;options = options || {}&lt;/code&gt; 는 함수의 인자에 아무것도 넣어주지 않는 경우, options의 기본값이 빈 객체가 되도록 만들어준다. 만약 빈 객체로 기본값을 설정하지 않는 경우 아래와 같은 오류가 발생하게 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;lsquo;Cannot read properties of undefined (reading &amp;lsquo;margin&amp;rsquo;)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;객체의 구조분해 할당을 사용하여 &lt;code&gt;exampleFuc&lt;/code&gt; 함수의 매개변수의 기본값을 설정해줄 수 있다.&lt;/p&gt;
&lt;pre class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot;&gt;&lt;code&gt;function exampleFuc({margin = 0, padding= 0, center = false} = {}){
    return {
        margin,
        padding,
        center,
    };
}

console.log(exampleFuc()); // {margin: 0, padding: 0, center: false}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;매개변수를 구조분해 할당하여 기본값을 설정한&amp;nbsp;&lt;code&gt;{margin = 0, padding= 0, center = false}&lt;/code&gt; 부분은 &lt;b&gt;기본 매개변수(default parameter)&lt;/b&gt;라고 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여기서 주의해야 하는 점은 &lt;b&gt;ES6의 기본값 매개변수는 파라미터가 정의되지 않고 undefined 값인 경우에만 기본 값을 할당&lt;/b&gt;한다. 그렇게 때문에, || 연산자를 통한 지역변수의 재정의 방식과는 동작이 다르므로, 주의해서 사용해야 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot;&gt;&lt;code&gt;function exampleFuc({margin = 0, padding= 0, center = 0} = {}){
    return {
        margin,
        padding,
        center,
    };
}

console.log(exampleFuc({margin : null, padding: 0, center : 0}));
// {margin: null, padding: 0, center: false}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;|| 연산자는 null 값이 들어왔을 때, null을 &lt;code&gt;falsy&lt;/code&gt;한 값으로 판단하여 지정된 기본값으로 대체되지만, 기본 매개변수의 경우 null을 값으로 인식하여 기본값이 대체되지 않는다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style3&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;매개변수로 반드시 값이 들어와야 하는데, 값이 들어오지 않았을 때 사용자에게 에러를 발생하도록 만들고 싶다면 어떻게 해야할까?&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot;&gt;&lt;code&gt;const required = (argName) =&amp;gt; {
    throw new Error(`required is ${argName}`)
}

function exampleFuc({item = required('items'), margin = 0, padding= 0, center = 0} = {}){
    return {
        margin,
        padding,
        center,
    };
}

console.log(exampleFuc({margin : 10, padding: 0, center : 0}));
// required is items&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;code&gt;required&lt;/code&gt; 함수를 기본값으로 대체하면, &lt;code&gt;item&lt;/code&gt;의 값이 작성되지 않은 경우 &lt;code&gt;required&lt;/code&gt;함수를 실행하여 에러를 발생시켜 반드시 값을 지정해야 함을 알려줄 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하지만 타입스크립트를 사용하게 되면 이와 같은 문제를 쉽게 해결할 수 있다고 생각된다 &lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Javascript</category>
      <category>default parameter</category>
      <category>default value</category>
      <category>javascript</category>
      <category>기본값</category>
      <category>자바스크립트</category>
      <author>후끈후끈</author>
      <guid isPermaLink="true">https://likelacoste.tistory.com/77</guid>
      <comments>https://likelacoste.tistory.com/77#entry77comment</comments>
      <pubDate>Thu, 22 Jun 2023 15:19:44 +0900</pubDate>
    </item>
    <item>
      <title>{ display : none } &amp;amp; { visibility : hidden }</title>
      <link>https://likelacoste.tistory.com/76</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre class=&quot;css&quot;&gt;&lt;code&gt;element{
    visibility : hidden
}

element{
  display : none
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;code&gt;display : none&lt;/code&gt; 과 &lt;code&gt;visibility : hidden&lt;/code&gt; 은 사용자의 화면에 보이지 않게 해준다는 공통점이 있다. 그렇다면 어떤 차이점이 있을까?&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;code&gt;display : none&lt;/code&gt;은 해당 요소가 페이지에서 완전히 제거되고 레이아웃에 영향을 주지 않는다.(스크린 리더도 해당 요소를 읽을 수 없다.)&lt;/li&gt;
&lt;li&gt;&lt;code&gt;visibility : hidden&lt;/code&gt;은 해당 요소를 화면에 보이지 않게 하지만, 레이아웃에 그대로 남아있어 빈 상자로 렌더링 된다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class=&quot;codepen&quot; style=&quot;height: 289.7209777832031px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;&quot; data-height=&quot;289.7209777832031&quot; data-theme-id=&quot;dark&quot; data-default-tab=&quot;html,result&quot; data-slug-hash=&quot;vYQNxWy&quot; data-user=&quot;DJ-Shin&quot; data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;See the Pen &lt;a href=&quot;https://codepen.io/DJ-Shin/pen/vYQNxWy&quot;&gt; Untitled&lt;/a&gt; by DJ Shin (&lt;a href=&quot;https://codepen.io/DJ-Shin&quot;&gt;@DJ-Shin&lt;/a&gt;) on &lt;a href=&quot;https://codepen.io&quot;&gt;CodePen&lt;/a&gt;.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;script src=&quot;https://cpwebassets.codepen.io/assets/embed/ei.js&quot;&gt;&lt;/script&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;&quot;display : none&quot; 또는 &quot;&lt;span style=&quot;text-align: left;&quot;&gt;visibility : hidden&quot; &lt;/span&gt;을 하게 되면 DOM 트리에 있을까, 없을까?&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;둘다 DOM 트리에 포함되어 있다. 둘의 차이는 렌더 트리에서 나타나게 된다. &quot;display : none&quot;의 경우 렌더 트리에서 와전히 제거되어 레이아웃에서 보이지 않게 되는 반면에, &amp;nbsp;&quot;visibility : hidden&quot;의 경우 해당 요소가 화면에 보이지 않지만 레이아웃에 그대로 존재한다.&amp;nbsp;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&quot;display : none&quot; 와 &quot;visibility : hidden&quot;의 차이를 명확하게 알고 상황에 적절하게 사용하도록 하자.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>CSS</category>
      <category>CSS</category>
      <category>Display</category>
      <category>visibility</category>
      <author>후끈후끈</author>
      <guid isPermaLink="true">https://likelacoste.tistory.com/76</guid>
      <comments>https://likelacoste.tistory.com/76#entry76comment</comments>
      <pubDate>Tue, 13 Jun 2023 17:53:29 +0900</pubDate>
    </item>
    <item>
      <title>이진탐색(Binary Search)</title>
      <link>https://likelacoste.tistory.com/75</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;이진탐색은 &lt;b&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;정렬된&lt;/span&gt; 배열 리스트&lt;/b&gt;에서 원하는 요소를 찾을 때 사용하는 탐색 알고리즘이다. 배열에서 탐색범위를 절반씩 좁혀가면서 특정한 값을 찾는 방법인데, 속도가 빠르고 효율적이여서 알아두면 좋은 알고리즘이다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;b&gt;❗️ indexOf 메서드를 사용하면 원하는 값을 찾을 수 있는데, 이진탐색이 필요할까?&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;indexOf 메서드의 시간 복잡도는 O(n)이고, 이진탐색의 시간 복잡도는 O(log n)이다. 그렇기 때문에 정렬된 배열이 주어진다면 indexOf 메서드보다 이진탐색을 사용하는게 더 빠르고 효율적이다.&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;위에서 설명했듯이 이진탐색은 &lt;b&gt;탐색범위를 절반씩 좁혀가며 값을 찾는 방법&lt;/b&gt;이다. 이진탐색의 원리에 대해 생각해보자.&lt;/span&gt;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt;1. 배열에서 중간 값을 찾는다.&lt;br /&gt;2. 찾는 값이 중간 값보다 크면 탐색 범위를 중간부터 끝까지, 작다면 탐색 범위를 처음부터 중간까지로 변경한다.&lt;br /&gt;3. 중간 값이 원하는 값과 같을 때까지 위 과정을 반복한다.&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;예시를 통해서 이진탐색이 진행되는 과정을 알아보자.&lt;/p&gt;
&lt;pre class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot;&gt;&lt;code&gt;let target = 23;
let arr = [1, 2, 3, 9, 10, 15, 23, 30, 35, 40];&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;배열의 중간 값은 10이다. 23은 10보다 큰 숫자이기 때문에 찾는 범위를 [15, 23, 30, 25, 40]으로 줄인다.&lt;/li&gt;
&lt;li&gt;[15, 23, 30, 25, 40] 에서 중간 값은 30이다. 23은 30보다 작은 숫자이기 때문에 찾는 범위를 [15, 23]으로 줄인다.&lt;/li&gt;
&lt;li&gt;[15, 23] 에서 중간 값은 15이다. 23은 15보다 크기 때문에 찾는 범위를 [23]으로 줄인다.&lt;/li&gt;
&lt;li&gt;[23] 에서 중간 값은 23이다. 여기서 23을 찾을 수 있다.&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;위 과정을 코드로 작성하면 아래와 같다.&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot;&gt;&lt;code&gt;function binarySearch(arr, target) {
    let low = 0;
    let hight = arr.length - 1;

    while (low &amp;lt;= hight) {
      let middle = Math.floor((low + hight) / 2);

      if (target &amp;lt; arr[middle]){
        hight = middle - 1;
      } else if (target &amp;gt; arr[middle]){
        low = middle + 1;
      } else {
        return middle;
      }
    }
    return -1;
  }

console.log(binarySearch([1, 2, 3, 9, 10, 15, 23, 30, 35, 40], 10)); // 4
console.log(binarySearch([1, 2, 5, 6, 7, 8, 9, 10, 11, 12], 10)); // 7
console.log(binarySearch([10, 20, 30, 40, 50, 60, 70], 80)); // -1&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;code&gt;binarySearch&lt;/code&gt; 함수는 정렬된 배열이 주어졌을 때, 찾고자 하는 값을 찾는다면 해당 값의 인덱스를 반환하고, 없다면 -1을 반환하는 함수이다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>알고리즘</category>
      <category>binary search</category>
      <category>javascript</category>
      <category>알고리즘</category>
      <category>이진탐색</category>
      <category>자바스크립트</category>
      <author>후끈후끈</author>
      <guid isPermaLink="true">https://likelacoste.tistory.com/75</guid>
      <comments>https://likelacoste.tistory.com/75#entry75comment</comments>
      <pubDate>Wed, 31 May 2023 16:17:32 +0900</pubDate>
    </item>
    <item>
      <title>투 포인터 패턴</title>
      <link>https://likelacoste.tistory.com/74</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;투 포인터(Two Pointers)&lt;/b&gt;&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;1차원 배열에서 각자 다른 원소를 가리키는 2개의 포인터를 조작하여 목표한 값을 구한다.&lt;/li&gt;
&lt;li&gt;완전 탐색 O(n^2)솔루션을 O(n)으로 성능을 향상 시킬 수 있다.&lt;/li&gt;
&lt;li&gt;연속된 구간의 원소 또는 정렬된 배열에서 무언가를 구할 때도 사용할 수 있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&amp;nbsp;&lt;/h2&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;정렬된 배열&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;정렬된 배열에서 두개의 원소의 합이 x와 같은지를 확인하고, x와 같다면 각각의 원소의 인덱스를 담은 배열을 반환하여라. (만약 두 원소의 합이 x와 같은 것이 없다면 &lt;code&gt;[-,1 -1]&lt;/code&gt;을 반환)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;출력 예시)&lt;/p&gt;
&lt;pre class=&quot;angelscript&quot;&gt;&lt;code&gt;solution([2, 4, 5, 7, 11, 15], 15); // [4, 11]
solution([-3, -2, -1, 0, 1, 2, 3]);// [-3, 3]
solution([-2, 0, 1, 3]);// [-1, -1]&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;배열을 완전탐색하여 주어진 조건의 값을 찾으면 아래와 같이 코드를 작성할 수 있다.&lt;/p&gt;
&lt;pre class=&quot;matlab&quot;&gt;&lt;code&gt;function solution(arr, x){
    for (let i = 0; i &amp;lt; arr.length; i++) {
      for (let j = i + 1; j &amp;lt; arr.length; j++) {
        if (arr[i] + arr[j] === x) {
          return [arr[i], arr[j]];
        }
      }
    }
    return[-1, -1]
  };&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위 코드는 반복문을 이중으로 사용하고 있기 때문에 시간복잡도는 O(n^2)이 된다. 이 방법으로도 주어진 문제를 해결 할 수 있지만 배열의 길이가 길어질 수록 반복 횟수는 많아지게 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;투 포인터 패턴을 어떻게 적용할 수 있을까?&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt;1. 정렬된 배열을 &lt;b&gt;두 지점(처음 : left, 마지막 : right&lt;/b&gt;)으로 나눠서 탐색을 시작한다.&lt;br /&gt;2. 배열의 left 요소와 right 요소의 합이 x보다 작다면, left 포인터를 한칸 뒤로 이동한다.&lt;br /&gt;3. 배열의 left 요소와 right 요소의 합이 x보다 크다면, right 포인터를 한칸 앞으로 이동한다.&lt;br /&gt;4. 배열의 left 요소와 right 요소의 합이 x와 같다면, left의 요소와 right의 요소를 배열에 담아 반환한다.&lt;br /&gt;5. 모든 과정에서 두 요소의 합이 x와 같은 것이 없다면, [-1, -1]을 반환한다.&lt;/blockquote&gt;
&lt;pre class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot;&gt;&lt;code&gt;const arr = [2, 4, 5, 7, 11, 15];
        //left(2)               right(15)        ---- 17 : right-1
const arr = [2, 4, 5, 7, 11, 15];
        //left(2)              right(11)         ---- 13 : left+1
const arr = [2, 4, 5, 7, 11, 15];
            //left(4)          right(11)         ---- 15 : [4, 11] 반환&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위 과정을 코드로 작성하면 아래와 같다.&lt;/p&gt;
&lt;pre class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot;&gt;&lt;code&gt;function  solution(arr, x){
    let left = 0;
    let right = arr.length - 1;

    while(left &amp;lt; right){
        let sum = arr[left] + arr[right]

        if(sum === x){
            return [arr[left], arr[right]];
        }
        else if(sum &amp;lt; x){
            left += 1;
        }
        else if(sum &amp;gt; x){
            right -= 1;
        }

    }

    return [-1, -1];
}&lt;/code&gt;&lt;/pre&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&amp;nbsp;&lt;/h2&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;연속된 부분 배열&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;주어지는 배열에서, 원소들의 합이 x인 연속 부분배열의 개수를 반환하여라.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;출력 예시)&lt;/p&gt;
&lt;pre class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot;&gt;&lt;code&gt;solution([1, 3, 6, 5, 2, 7, 9], 9) // 3
solution([1, 2, 3, 4, 5, 6], 6) // 2
solution([1, 2, 3, 5, 5, 7, 8, 9, 10], 10) // 3&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;완전탐색하여 주어진 배열 중에 합이 x인 연속 부분배열의 개수를 찾으면 아래와 같이 코드를 작성할 수 있다.&lt;/p&gt;
&lt;pre class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot;&gt;&lt;code&gt;function solution(arr, x){
    let count = 0;
    for(let i=0; i&amp;lt;arr.length; i++){
        let sum = 0;
        for(let j=i; j&amp;lt;arr.length; j++){
            sum += arr[j];
            if(sum &amp;gt; x){
                break;
            }
            if(sum === x){
                count += 1;
                break;
            }
        }

    }
    return count;
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위 코드도 반복문을 이중으로 사용하고 있기 때문에 시간복잡도는 O(n^2)이 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;투 포인터 패턴을 적용해보자.&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt;1. &lt;b&gt;두 지점(left, right)&lt;/b&gt; 모두 배열의 첫번째 요소에서 출발한다.&lt;br /&gt;2. 두 지점의 합이 x보다 작다면, right 포인터를 한칸 뒤로 옮긴후, 배열의 right 요소를 더한다.&lt;br /&gt;3. 두 지점의 합이 x보다 크다면, left 포인터를 한칸 뒤로 옮긴후, 배열의 left 요소를 뺀다.&lt;br /&gt;4. 두 지점의 합이 x와 같다면, count에 1을 더하고 left 포인터를 한칸 뒤로 옮긴다.&lt;br /&gt;5. right 포인터가 배열의 끝 지점이 도달하면 count 값을 반환한다.&lt;br /&gt;6. 위 과정을 코드로 작성하면 아래와 같다.&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위 과정을 코드로 작성하면 아래와 같다.&lt;/p&gt;
&lt;pre class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot;&gt;&lt;code&gt;function solution(arr, x) {
    let count = 0;
    let sum = 0;
    let left = 0;
    let right = 0;

    while(right&amp;lt;=arr.length){
        if(sum === x){
            count += 1;
            sum -= arr[left];
            left += 1;
        }else if(sum &amp;lt; x){
            sum += arr[right];
            right += 1;
        }else if(sum &amp;gt; x){
            sum -= arr[left];
            left += 1;
        }
    }
    return count;
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>알고리즘</category>
      <category>two pointers</category>
      <category>알고리즘</category>
      <category>연속 부분배열</category>
      <category>투 포인터</category>
      <author>후끈후끈</author>
      <guid isPermaLink="true">https://likelacoste.tistory.com/74</guid>
      <comments>https://likelacoste.tistory.com/74#entry74comment</comments>
      <pubDate>Fri, 26 May 2023 19:01:40 +0900</pubDate>
    </item>
    <item>
      <title>배열 안에 중복되는 요소 제거</title>
      <link>https://likelacoste.tistory.com/73</link>
      <description>&lt;pre class=&quot;angelscript&quot;&gt;&lt;code&gt;let numbers = [1, 2, 3, 4, 2, 6, 6, 5];&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;&lt;code&gt;numbers&lt;/code&gt;이라는 배열 안에는 중복되는 숫자가 있다. 중복되는 숫자(2, 6)를 제거하는 방법은 무엇이 있을까?&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;1. indexOf()&lt;/span&gt;&lt;/h2&gt;
&lt;pre class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot;&gt;&lt;code&gt;function getUniqueNumbers(numbers){
    return numbers.filter((num, index) =&amp;gt; index === numbers.indexOf(num));
}

console.log(getUniqueNumbers([1, 2, 3, 4, 2, 6, 6, 5])); // [1, 2, 3, 4, 6, 5]&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;indexOf() 메서드는 배열에서 지정된 요소가 존재한다면 해당 요소의 인덱스를 반환하고, 존재하지 않으면 -1을 반환한다. 이때 찾고자 하는 요소가 배열 안에 여러개가 존재한다면 가장 앞에 있는 요소의 인덱스를 반환한다.&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot;&gt;&lt;code&gt;let arr = [1, 2, 3, 4, 2];
console.log(arr.indexOf(2)); // 1&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;&lt;span style=&quot;background-color: #e6f5ff; text-align: start;&quot;&gt;&amp;nbsp;getUniqueNumbers &lt;/span&gt;&lt;span style=&quot;letter-spacing: 0px;&quot;&gt;&amp;nbsp;함수의 매개변수로 들어오는 배열(numbers)에 filter() 메서드를 사용하여, filter() 메서드의 콜백함수에 전달받은 인덱스의 값(index)이 현재 엘리먼트(num)가 indexOf()의 반환 값과 같은 숫자들만 다시 새로운 배열로 만들어 반환하도록 하면 중복된 숫자가 제거된 배열을 얻을 수 있다.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;table style=&quot;height: 153px;&quot; width=&quot;425&quot; data-ke-align=&quot;alignLeft&quot; data-ke-style=&quot;style15&quot;&gt;
&lt;tbody&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;height: 17px; text-align: center;&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;&lt;b&gt;num&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;height: 17px; text-align: center;&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;&lt;b&gt;index&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;height: 17px; text-align: center;&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;&lt;b&gt;indexOf&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;height: 17px; text-align: center;&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;&lt;b&gt;result&lt;/b&gt;&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;text-align: center; height: 17px;&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;1&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;text-align: center; height: 17px;&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;0&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;text-align: center; height: 17px;&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;0&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;text-align: center; height: 17px;&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;true&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;height: 17px; text-align: center;&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;2&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;height: 17px; text-align: center;&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;1&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;height: 17px; text-align: center;&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;1&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;height: 17px; text-align: center;&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;true&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;height: 17px; text-align: center;&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;3&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;height: 17px; text-align: center;&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;2&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;height: 17px; text-align: center;&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;2&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;height: 17px; text-align: center;&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;true&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;height: 17px; text-align: center;&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;4&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;height: 17px; text-align: center;&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;3&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;height: 17px; text-align: center;&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;3&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;height: 17px; text-align: center;&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;true&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;height: 17px; text-align: center;&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;2&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;height: 17px; text-align: center;&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;4&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;height: 17px; text-align: center;&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;1&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;height: 17px; text-align: center;&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;false&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;height: 17px; text-align: center;&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;6&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;height: 17px; text-align: center;&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;5&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;height: 17px; text-align: center;&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;5&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;height: 17px; text-align: center;&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;true&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;height: 17px; text-align: center;&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;6&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;height: 17px; text-align: center;&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;6&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;height: 17px; text-align: center;&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;5&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;height: 17px; text-align: center;&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;false&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 17px;&quot;&gt;
&lt;td style=&quot;height: 17px; text-align: center;&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;5&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;height: 17px; text-align: center;&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;7&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;height: 17px; text-align: center;&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;7&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;height: 17px; text-align: center;&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;true&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&amp;nbsp;&lt;/h2&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;2. caching / frequency map&lt;/span&gt;&lt;/h2&gt;
&lt;pre class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot;&gt;&lt;code&gt;function getUniqueNumbers(numbers){
    const uniqueNumbers = {};
    const result = [];

    for(let num of numbers){
        if(!uniqueNumbers[num]){
            result.push(num);
        }
        uniqueNumbers[num] = num;
    }
    return result;
}

console.log(getUniqueNumbers([1, 2, 3, 4, 2, 6, 6, 5])); // [1, 2, 3, 4, 6, 5]&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;&lt;span style=&quot;background-color: #e6f5ff; text-align: start;&quot;&gt;&amp;nbsp;getUniqueNumbers&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;text-align: start;&quot;&gt;&amp;nbsp;함수의 매개변수로 들어오는 배열을 for...of 명령문을 사용하여 각각의 요소를 uniqueNumbers 객체의 key와 valuse 값으로 넣어준다. 이때 해당 요소가 uniqueNumbers 객체에 존재하지 않는다면 result 배열에 넣어준다.(배열(numbers)의 숫자 중에 처음으로 만난 숫자이기 때문)&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000; text-align: start; font-family: 'Nanum Gothic';&quot;&gt;for...of 명령문이 끝나게 되면 result 안에는 중복되지 않은 숫자만 들어있게 된다.&lt;/span&gt;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&amp;nbsp;&lt;/h2&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;3. Set()&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;&lt;a style=&quot;color: #000000;&quot; href=&quot;https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/Set&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;Set 객체&lt;/a&gt;는 자료형에 관계 없이 원시 값과 객체 참조 모두 중복없이 유일한 값을 저장할 수 있다.&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1684896890686&quot; class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;let test = new Set();
let obj = {a:1, b:2}

test.add(1)
test.add(2)
test.add(3)
test.add(1)
test.add(obj)


console.log(test); // Set {1, 2, 3, {a:1, b:2}}
console.log(test.has(1)); // true
console.log(test.has(obj)); // true
console.log(test.has(4)); // false
console.log(test.size); // 4&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot;&gt;&lt;code&gt;function getUniqueNumbers(numbers){
    return [...new Set(numbers)];
}

console.log(getUniqueNumbers([1, 2, 3, 4, 2, 6, 6, 5])); // [1, 2, 3, 4, 6, 5]&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;생성자를 사용하여 Set 객체를 만든 후, 함수의 매개변수로 들어오는 배열을 넣어주게 되면 배열 안에 중복요소를 필터링 한 상태로 초기화 한다. 그런 다음에 스프레드 연산자를 사용하여 배열로 변환한 후 반환하게 되면 중복된 숫자가 제거 된 배열을 얻을 수 있다.&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>알고리즘</category>
      <category>frequency map</category>
      <category>javascript</category>
      <category>set()</category>
      <category>배열 안에 중복 제거</category>
      <category>알고리즘</category>
      <category>자바스크립트</category>
      <author>후끈후끈</author>
      <guid isPermaLink="true">https://likelacoste.tistory.com/73</guid>
      <comments>https://likelacoste.tistory.com/73#entry73comment</comments>
      <pubDate>Wed, 24 May 2023 12:06:24 +0900</pubDate>
    </item>
    <item>
      <title>[JavaScript] null 병합 할당 연산</title>
      <link>https://likelacoste.tistory.com/72</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;null 병합 연산자를 사용하면 짧은 문법으로 여&lt;b&gt;러 피연산자 중에 그 값이 &amp;lsquo;확정되어 있는&amp;rsquo; 변수&lt;/b&gt;를 찾을 수 있다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;code&gt;a ?? b&lt;/code&gt;&lt;/span&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;a가 null도 아니고 undefined도 아니면 a&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;그 외의 경우는 b&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;null 병합 연산자를 사용하지 않고 &lt;code&gt;let x = a ?? b&lt;/code&gt;와 동일하게 동작하는 코드를 작성하면 아래와 같다.&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot;&gt;&lt;code&gt;let x = (a !== null &amp;amp;&amp;amp; a !== undefined) ? a: b&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;확실히 코드의 길이가 길어지는 것을 볼 수 있다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;이처럼 null 병합 연산자를 사용하면 코드를 조금 더 간단하게 작성할 수 있다.&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot;&gt;&lt;code&gt;let firstName = null;
let lastName = null;
let nickName = &quot;홍길동&quot;;

console.log(firstName ?? lastName ?? nickName ?? &quot;익명의 사용자&quot;); // 홍길동&lt;/code&gt;&lt;/pre&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;code&gt;&lt;/code&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;&lt;code&gt;&lt;/code&gt;&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&amp;nbsp;&lt;/h3&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;&lt;code&gt;??&lt;/code&gt; 와 &lt;code&gt;||&lt;/code&gt; 의 차이&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;null 병합 연산자는 OR 연산자( || ) 와 유사하게 보인다. 위 예시에서 &lt;code&gt;??&lt;/code&gt;를 &lt;code&gt;||&lt;/code&gt;로 바꿔도 결과는 동일하다. 하지만 두 연산자 사이에는 차이점이 있다.&lt;/span&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;code&gt;||&lt;/code&gt; 는 첫 번째 truthy 값을 반환한다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;code&gt;??&lt;/code&gt; 는 첫 번째 정의된(defined) 값을 반환한다.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;u&gt;&lt;b&gt;null과 undefined, 0을 구분해서 다뤄야 하는 경우&lt;/b&gt;&lt;/u&gt;, 이 차이점은 큰 역할을 한다.&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;maxima&quot;&gt;&lt;code&gt;let height = height ?? 100;

// height에 값이 정의되지 않을 경우 height에는 100이 할당된다.&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;code&gt;??&lt;/code&gt; 연산자와 &lt;code&gt;||&lt;/code&gt; 연산자를 비교해보자.&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;javascript&quot; data-ke-language=&quot;javascript&quot;&gt;&lt;code&gt;let height = 0;

console.log(height || 100); // 100

console.log(height ?? 100); // 0&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;code&gt;height || 0&lt;/code&gt; 은 height에 0을 할당했지만 0을 falsy한 값으로 취급했기 때문에 null이나 undefined를 할당한 것과 동일하게 처리한다. 그렇기 때문에 &lt;code&gt;height || 100&lt;/code&gt;의 결과는 100이다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;반면에 &lt;code&gt;height ?? 100&lt;/code&gt; 의 결과는 height 정확하게 null 이나 undefined일 경우에만 100 되기 때문에 &lt;code&gt;height ?? 100&lt;/code&gt; 의 결과는 0이 된다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;이러한 특징 때문에 높이처럼 0이 할당될 수 있는 변수를 사용해 기능을 개발해야 한다면 || 연산자 보다 ?? 연산자가 적합하다.&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;참고&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;&lt;a href=&quot;https://ko.javascript.info/nullish-coalescing-operator&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://ko.javascript.info/nullish-coalescing-operator&lt;/a&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Javascript</category>
      <category>javascript</category>
      <category>null 병합 할당 연산</category>
      <category>자바스크립트</category>
      <author>후끈후끈</author>
      <guid isPermaLink="true">https://likelacoste.tistory.com/72</guid>
      <comments>https://likelacoste.tistory.com/72#entry72comment</comments>
      <pubDate>Wed, 3 May 2023 15:34:26 +0900</pubDate>
    </item>
    <item>
      <title>[JavaScript] AND와 OR연산자</title>
      <link>https://likelacoste.tistory.com/71</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;user의 정보를 담고 있는 객체가 있다. user라는 객체의 name이라는 값이 확실하지 않을 때, 아래와 같이 조건문을 사용할 수 있다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;code.png&quot; data-origin-width=&quot;730&quot; data-origin-height=&quot;724&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/b6bGy5/btsdFf4Gljt/IyQ3jEyhAUb25bYuqEeOd1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/b6bGy5/btsdFf4Gljt/IyQ3jEyhAUb25bYuqEeOd1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/b6bGy5/btsdFf4Gljt/IyQ3jEyhAUb25bYuqEeOd1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fb6bGy5%2FbtsdFf4Gljt%2FIyQ3jEyhAUb25bYuqEeOd1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;666&quot; height=&quot;661&quot; data-filename=&quot;code.png&quot; data-origin-width=&quot;730&quot; data-origin-height=&quot;724&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;위 조건문은 조건 중 하나라도 참일 경우 'no name'이라는 값을 반환하고, 거짓인 경우 해당 객체의 name 값을 반환하게 된다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;그런데 undefined와 false, '', null, 0은 &lt;a href=&quot;https://developer.mozilla.org/ko/docs/Glossary/Falsy&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;거짓같은 값(falsy)&lt;/a&gt;이기 때문에 항상 false로 평가되는 값이다. 때문에 조건문을 아래와 같이 작성할 수 있다.&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;pgsql&quot;&gt;&lt;code&gt;if(user.name){
    console.log(user.name);
}else{
    console.log('no name');
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;여기서 OR연산자를 사용하면 코드를 더 간단하게 작성할 수 있다.&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;pgsql&quot;&gt;&lt;code&gt;console.log(user.name || 'no name');&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;위 코드는 앞의 값이 존재하면 앞의 값을 반환하고 그렇지 않으면 뒤의 값을 반환하게 된다. 때문에 user.name이 존재할 경우 해당 값을 반환하게 되고, 존재하지 않을 경우 'no name'을 반환하게 된다. 이러한&lt;b&gt; OR연산자는 기본값을 지정할 때 많이 사용한다.&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;다음의 조건문을 보자.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;code.png&quot; data-origin-width=&quot;656&quot; data-origin-height=&quot;544&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/d1ge3Y/btsdFgJhRbk/17JBZBKIdDNT3POUKgJpJK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/d1ge3Y/btsdFgJhRbk/17JBZBKIdDNT3POUKgJpJK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/d1ge3Y/btsdFgJhRbk/17JBZBKIdDNT3POUKgJpJK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fd1ge3Y%2FbtsdFgJhRbk%2F17JBZBKIdDNT3POUKgJpJK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;666&quot; height=&quot;552&quot; data-filename=&quot;code.png&quot; data-origin-width=&quot;656&quot; data-origin-height=&quot;544&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;user.age가 19를 초과하는 경우에는 '성인'을 반환하게 되고, 그렇지 않은 경우에는 false를 반환하게 된다. 여기서 AND연산자를 사용하면 위 조건문을 더 간단하게 작성할 수 있다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre class=&quot;pgsql&quot;&gt;&lt;code&gt;console.log(user.age &amp;gt; 19 &amp;amp;&amp;amp; '성인');&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;두 개의 값이 모두 참인 경우 마지막 값을 반환하고, 둘 중에 하나라도 거짓인 경우 false를 반환하게 된다. 이러한 &lt;b&gt;AND연산자는 특수한 상황에서 조건문 대용으로 사용할 수 있다.&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Javascript</category>
      <category>And연산자</category>
      <category>javascript</category>
      <category>Or연산자</category>
      <category>자바스크립트</category>
      <author>후끈후끈</author>
      <guid isPermaLink="true">https://likelacoste.tistory.com/71</guid>
      <comments>https://likelacoste.tistory.com/71#entry71comment</comments>
      <pubDate>Tue, 2 May 2023 15:44:25 +0900</pubDate>
    </item>
    <item>
      <title>[React] useMemo와 useCallback</title>
      <link>https://likelacoste.tistory.com/70</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;메모이제이션이란?&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;메모이제이션(memoization)은 컴퓨터 프로그램이 동일한 계산을 반복해야할 때, 이전에 계산한 값을 메모리에 저장함으로써 &lt;b&gt;동일한 계산의 반복 수행을 제거하여 실행 속도를 빠르게&lt;/b&gt; 하는 기술을 말한다.(캐시로 성능을 높이는 프로그램 기법)&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;알고리즘 문제를 풀 때 많이 사용되는 재귀함수(피보나치 수열)를 통해 메모이제이션을 알아보도록 하자.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;피보나치 수열은 0과 1로 시작해서, 이전 두 개의 숫자를 더한 값을 다음 항으로 하는 수열을 말한다. 즉, 0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610, 987, ...과 같은 형태를 가지며, 각 항은 그 이전 두 항을 더한 값으로 계산된다.&lt;/span&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;이 피보나치 수열을 재귀함수를 사용해서 함수를 만들면 아래와 같이 만들 수 있다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre class=&quot;typescript&quot; data-ke-language=&quot;typescript&quot;&gt;&lt;code&gt;const fibonacci = (n) =&amp;gt; {

  if ( n &amp;lt;= 1 ) {
    return n;
  }

  return fibonacci(n-1) + fibonacci(n-2);
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;위 함수는 fibonacci 함수를 재귀적으로 수행하는데, 계산의 양이 늘어날 수록 계산의 중복으로 인해 시간복잡도는 증가하게 된다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;예를 들어 fibonacci(5)를 실행하면 fibonacci(4) + fibonacci(3) + &amp;hellip; 순서로 실행하게 되는데, 여기서 fibonacci(4)는 다시 fibonacci(3) + fibonacci(2) + &amp;hellip; 순서로 실행하게 된다. 이 과정 속에서 한 번 계산 했던 것을 반복하는 것을 볼 수 있다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;이때 한 번 계산한 결과를 저장해두고 거기서 값을 꺼내쓰면 계산의 중복이 발생하지 않게되어 효율적인 함수가 된다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre class=&quot;excel&quot;&gt;&lt;code&gt;const fibonacci = (n,memo) =&amp;gt; {
    memo = memo || {}

    if (memo[n]) {
        return memo[n]
    }

    if (n &amp;lt;= 1) {
        return n
    }

    return memo[n] = fibonacci(n - 1, memo) + fibonacci(n - 2, memo)
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;이를 &lt;b&gt;메모이제이션&lt;/b&gt;이라고 한다.&lt;/span&gt;&lt;/p&gt;
&lt;h1&gt;&amp;nbsp;&lt;/h1&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;useMemo&lt;/span&gt;&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;useMemo는 컴포넌트 내부에서 계산된 값을 메모이제이션하여, 값이 변경되지 않았으면 이전의 값을 재사용하여 연산을 최적화 하는 React Hook이다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre class=&quot;typescript&quot; data-ke-language=&quot;typescript&quot;&gt;&lt;code&gt;// Average.tsx

import React, { useState, useRef } from &quot;react&quot;;

const getAverage = (numbers: number[]) =&amp;gt; {
  console.log(&quot;평균값 계산중..&quot;);
  if (numbers.length === 0) return 0;
  const sum = numbers.reduce((a: number, b: number) =&amp;gt; a + b);
  return sum / numbers.length;
};

const Average = () =&amp;gt; {
  const [list, setList] = useState&amp;lt;number[]&amp;gt;([]);
  const [number, setNumber] = useState&amp;lt;string&amp;gt;(&quot;&quot;);
  const inputEl = useRef&amp;lt;HTMLInputElement&amp;gt;(null);

  const onChange = useCallback((e: React.ChangeEvent&amp;lt;HTMLInputElement&amp;gt;) =&amp;gt; {
    setNumber(e.target.value);
  }, []);

  const onInsert = () =&amp;gt; {
    const nextList = list.concat(Number(number));
    setList(nextList);
    setNumber(&quot;&quot;);
    inputEl?.current?.focus();
  };

  return (
    &amp;lt;div&amp;gt;
      &amp;lt;input value={number} onChange={onChange} ref={inputEl} /&amp;gt;
      &amp;lt;button onClick={onInsert}&amp;gt;등록&amp;lt;/button&amp;gt;
      &amp;lt;ul&amp;gt;
        {list.map((value, index) =&amp;gt; (
          &amp;lt;li key={index}&amp;gt;{value}&amp;lt;/li&amp;gt;
        ))}
      &amp;lt;/ul&amp;gt;
      &amp;lt;div&amp;gt;
        &amp;lt;b&amp;gt;평균값:&amp;lt;/b&amp;gt; {getAverage(list)}
      &amp;lt;/div&amp;gt;
    &amp;lt;/div&amp;gt;
  );
};

export default Average;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2023-04-26 18.06.32.png&quot; data-origin-width=&quot;1632&quot; data-origin-height=&quot;1276&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bobCRe/btscQcgLvRH/aHljOry78KbH4js70dJb11/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bobCRe/btscQcgLvRH/aHljOry78KbH4js70dJb11/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bobCRe/btscQcgLvRH/aHljOry78KbH4js70dJb11/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbobCRe%2FbtscQcgLvRH%2FaHljOry78KbH4js70dJb11%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;666&quot; height=&quot;521&quot; data-filename=&quot;스크린샷 2023-04-26 18.06.32.png&quot; data-origin-width=&quot;1632&quot; data-origin-height=&quot;1276&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;숫자를 등록하게 되면, 등록할 때뿐만 아니라 인풋 내용이 수정될 때도 getAverage 함수가 호출되는 것을 볼 수 있다. 평균값은 list가 변화될 때만 계산되야 하는데, input 값이 변경될 때마다 컴포넌트가 리렌더링 되면서 불필요하게 호출이 발생하게 된다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;useMemo Hook을 사용하면 이러한 작업을 최적화 할 수 있다. 렌더링하는 과정에서 특정 값이 바뀌었을 때만 연산을 실행하고, 원하는 값이 바뀌지 않았다면 이전에 연산했던 결과를 다시 사용하게 된다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre class=&quot;typescript&quot; data-ke-language=&quot;typescript&quot;&gt;&lt;code&gt;// Average.tsx

import React, { useState, useMemo, useRef } from &quot;react&quot;;

const getAverage = (numbers: number[]) =&amp;gt; {
  console.log(&quot;평균값 계산중..&quot;);
  if (numbers.length === 0) return 0;
  const sum = numbers.reduce((a: number, b: number) =&amp;gt; a + b);
  return sum / numbers.length;
};

const Average = () =&amp;gt; {
  const [list, setList] = useState&amp;lt;number[]&amp;gt;([]);
  const [number, setNumber] = useState&amp;lt;string&amp;gt;(&quot;&quot;);
  const inputEl = useRef&amp;lt;HTMLInputElement&amp;gt;(null);

  const onChange = useCallback((e: React.ChangeEvent&amp;lt;HTMLInputElement&amp;gt;) =&amp;gt; {
    setNumber(e.target.value);
  }, []);

  const onInsert = () =&amp;gt; {
    const nextList = list.concat(Number(number));
    setList(nextList);
    setNumber(&quot;&quot;);
    inputEl?.current?.focus();
  };

  const avg = useMemo(() =&amp;gt; getAverage(list), [list]);

  return (
    &amp;lt;div&amp;gt;
      &amp;lt;input value={number} onChange={onChange} ref={inputEl} /&amp;gt;
      &amp;lt;button onClick={onInsert}&amp;gt;등록&amp;lt;/button&amp;gt;
      &amp;lt;ul&amp;gt;
        {list.map((value, index) =&amp;gt; (
          &amp;lt;li key={index}&amp;gt;{value}&amp;lt;/li&amp;gt;
        ))}
      &amp;lt;/ul&amp;gt;
      &amp;lt;div&amp;gt;
        &amp;lt;b&amp;gt;평균값:&amp;lt;/b&amp;gt; {avg}
      &amp;lt;/div&amp;gt;
    &amp;lt;/div&amp;gt;
  );
};

export default Average;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2023-04-26 18.13.49.png&quot; data-origin-width=&quot;1638&quot; data-origin-height=&quot;1270&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cBCtBV/btscNSDgWmn/uGBHAiQXKwz9rk1npFfTn1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cBCtBV/btscNSDgWmn/uGBHAiQXKwz9rk1npFfTn1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cBCtBV/btscNSDgWmn/uGBHAiQXKwz9rk1npFfTn1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcBCtBV%2FbtscNSDgWmn%2FuGBHAiQXKwz9rk1npFfTn1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;666&quot; height=&quot;516&quot; data-filename=&quot;스크린샷 2023-04-26 18.13.49.png&quot; data-origin-width=&quot;1638&quot; data-origin-height=&quot;1270&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;코드를 위와 같이 작성해주면 list 배열의 내용이 바뀔 때만 getAverage 함수가 호출되는 것을 볼 수 있다.&lt;/span&gt;&lt;/p&gt;
&lt;h1&gt;&amp;nbsp;&lt;/h1&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;useCallback&lt;/span&gt;&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;useCallback은 useMem와 비슷한 React Hook 이다. useMemo는 특정 결과값을 재사용할 때 사용하는 반면에, useCallback 주로 렌더링 성능을 최적화해야 하는 상황에서 사용한다. useCallback은 특정 함수를 새로 만들지 않고 만들어 놨던 함수를 재사용하고 싶을 때 사용한다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;위에 구현한 Average 컴포넌트에서, onChage와 onInsert 함수는 컴포넌트가 리렌더링 될 때마다 새로 만들어져 사용된다. 대부분의 경우 이러한 방식은 문제가 없지만, 컴포넌트의 렌더링이 자주 발생하거나 렌더링해야 할 컴포넌트의 개수가 많아지면 이 부분을 최적화해 주는 것이 좋다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre class=&quot;typescript&quot; data-ke-language=&quot;typescript&quot;&gt;&lt;code&gt;// Average.tsx

import React, { useState, useMemo, useRef, useCallback } from &quot;react&quot;;

const getAverage = (numbers: number[]) =&amp;gt; {
  console.log(&quot;평균값 계산중..&quot;);
  if (numbers.length === 0) return 0;
  const sum = numbers.reduce((a: number, b: number) =&amp;gt; a + b);
  return sum / numbers.length;
};

const Average = () =&amp;gt; {
  const [list, setList] = useState&amp;lt;number[]&amp;gt;([]);
  const [number, setNumber] = useState&amp;lt;string&amp;gt;(&quot;&quot;);
  const inputEl = useRef&amp;lt;HTMLInputElement&amp;gt;(null);

  const onChange = useCallback((e: React.ChangeEvent&amp;lt;HTMLInputElement&amp;gt;) =&amp;gt; {
    setNumber(e.target.value);
  }, []);

  const onInsert = useCallback(() =&amp;gt; {
    const nextList = list.concat(Number(number));
    setList(nextList);
    setNumber(&quot;&quot;);
    inputEl?.current?.focus();
  }, [number, list]);

  const avg = useMemo(() =&amp;gt; getAverage(list), [list]);

  return (
    &amp;lt;div&amp;gt;
      &amp;lt;input value={number} onChange={onChange} ref={inputEl} /&amp;gt;
      &amp;lt;button onClick={onInsert}&amp;gt;등록&amp;lt;/button&amp;gt;
      &amp;lt;ul&amp;gt;
        {list.map((value, index) =&amp;gt; (
          &amp;lt;li key={index}&amp;gt;{value}&amp;lt;/li&amp;gt;
        ))}
      &amp;lt;/ul&amp;gt;
      &amp;lt;div&amp;gt;
        &amp;lt;b&amp;gt;평균값:&amp;lt;/b&amp;gt; {avg}
      &amp;lt;/div&amp;gt;
    &amp;lt;/div&amp;gt;
  );
};

export default Average;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;useCallback의 첫 번째 파라미터에는 생성하고 싶은 함수를 넣고, 두 번째 파라미터에는 배열을 넣어서 사용한다. 이 배열(Dependency Array - 의존성 배열)에는 어떤 값이 바뀌었을 때 함수를 새로 생성할지 명시해야 한다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;함수 내부에서 상태 값에 의존해야 하는 경우, 그 값을 반드시 두 번째 파라미터 안에 포함시켜야 한다. 예를들어 onInsert는 기존의 number와 list를 조회해서 nextList를 생성하기 때문에 배열 안에 number와 list를 넣어야 한다.&lt;/span&gt;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&amp;nbsp;&lt;/h3&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;useCallback을 사용하는 경우&lt;/span&gt;&lt;/b&gt;&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;함수 자체를 캐싱해야할 때&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;dependency를 확인해야 하는 함수인 경우&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;자식 컴포넌트에 prop으로 넘겨주는 함수인 경우&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;참고&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;a href=&quot;https://ko.legacy.reactjs.org/docs/hooks-reference.html#usememo&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://ko.legacy.reactjs.org/docs/hooks-reference.html#usememo&lt;/a&gt; &lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt; &lt;a href=&quot;https://react.vlpt.us/basic/17-useMemo.html&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://react.vlpt.us/basic/17-useMemo.html&lt;/a&gt;&amp;nbsp;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;a href=&quot;https://react.vlpt.us/basic/18-useCallback.html&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://react.vlpt.us/basic/18-useCallback.html&lt;/a&gt;&amp;nbsp;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;a href=&quot;https://jeonghwan-kim.github.io/2023/04/17/usememo-usecallback&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://jeonghwan-kim.github.io/2023/04/17/usememo-usecallback.&lt;/a&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>React</category>
      <category>React</category>
      <category>useCallback</category>
      <category>useMemo</category>
      <category>리액트</category>
      <category>메모이제이션</category>
      <author>후끈후끈</author>
      <guid isPermaLink="true">https://likelacoste.tistory.com/70</guid>
      <comments>https://likelacoste.tistory.com/70#entry70comment</comments>
      <pubDate>Wed, 26 Apr 2023 18:40:20 +0900</pubDate>
    </item>
    <item>
      <title>[React] React Router</title>
      <link>https://likelacoste.tistory.com/69</link>
      <description>&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;라우팅이란?&lt;/b&gt;&lt;/span&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;웹 애플리케이션에서 라우팅이란 사용자가 요청한 URL에 맞게 페이지를 보여주는 것을 의미한다. 프로젝트가 하나의 페이지로 구성되어 있다면 라우팅이 필요 없겠지만, 여러 페이지로 구성된 웹 애플리케이션은 페이지 별로 컴포넌트를 다르게해서 관리하기 때문에 라우팅 시스템이 필요하다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;React Router&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;React Router는 리액트의 라우팅 관련 라이브러리로 컴포넌트 기반으로 라우팅을 설정할 수 있다. 리액트에서 라우터를 적용하는 방법은 두가지가 있다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;1. BrowserRouter&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;리액트 라우터를 적용할 때는 react-router-dom에 내장되어 있는 BrowserRouter와 Routes, Rout 컴포넌트를 사용한다.&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;javascript&quot;&gt;&lt;code&gt;// Home.tsx

const Home = () =&amp;gt; {
  return (
    &amp;lt;div&amp;gt;
      &amp;lt;h1&amp;gt;여기는 Home 입니다.&amp;lt;/h1&amp;gt;
    &amp;lt;/div&amp;gt;
  );
};

export default Home;&lt;/code&gt;&lt;/pre&gt;
&lt;pre class=&quot;javascript&quot;&gt;&lt;code&gt;// About.tsx

const About = () =&amp;gt; {
  return (
    &amp;lt;div&amp;gt;
      &amp;lt;h1&amp;gt;여기는 About 입니다.&amp;lt;/h1&amp;gt;
    &amp;lt;/div&amp;gt;
  );
};

export default About;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;BrowserRouter 컴포넌트는 웹 애플리케이션에 HTML5의 History API를 사용하여 페이지를 새로 불러오지 않고도 주소를 변경하고 현재 주소의 경로에 관련된 정보를 리액트 컴포넌트에서 사용할 수 있게 해준다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;Route 컴포넌트는 사용자의 브라우저 주소 경로에 따라 원하는 컴포넌트를 보여주는 역할을 한다. Route 컴포넌트를 적용하기 위해서는 Routes 컴포넌트 내부에서 사용되어야 한다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre class=&quot;javascript&quot;&gt;&lt;code&gt;// App.tsx

import { BrowserRouter, Routes, Route } from &quot;react-router-dom&quot;;
import Home from &quot;./Home&quot;;
import About from &quot;./About&quot;;

const App = () =&amp;gt; {
  return (
    &amp;lt;BrowserRouter&amp;gt;
      &amp;lt;Routes&amp;gt;
        &amp;lt;Route path=&quot;/&quot; element={&amp;lt;Home /&amp;gt;}&amp;gt;&amp;lt;/Route&amp;gt;
        &amp;lt;Route path=&quot;/about&quot; element={&amp;lt;About /&amp;gt;}&amp;gt;&amp;lt;/Route&amp;gt;
      &amp;lt;/Routes&amp;gt;
    &amp;lt;/BrowserRouter&amp;gt;
  );
};

export default App;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imagegridblock&quot;&gt;
  &lt;div class=&quot;image-container&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/APlRY/btsbUqGTjlE/oZ3lrvmlNxJMieCjxunYK1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/APlRY/btsbUqGTjlE/oZ3lrvmlNxJMieCjxunYK1/img.png&quot; data-is-animation=&quot;false&quot; data-origin-width=&quot;666&quot; data-origin-height=&quot;565&quot; data-filename=&quot;edited_스크린샷 2023-04-22 09.44.54.png&quot; width=&quot;333&quot; height=&quot;283&quot; data-widthpercent=&quot;49.69&quot; style=&quot;width: 49.1106%; margin-right: 10px;&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/APlRY/btsbUqGTjlE/oZ3lrvmlNxJMieCjxunYK1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FAPlRY%2FbtsbUqGTjlE%2FoZ3lrvmlNxJMieCjxunYK1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;666&quot; height=&quot;565&quot;/&gt;&lt;/span&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/JgvxD/btsbSMDNb0r/oNWrqoIInr4TtMoP0vJVVk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/JgvxD/btsbSMDNb0r/oNWrqoIInr4TtMoP0vJVVk/img.png&quot; data-is-animation=&quot;false&quot; data-origin-width=&quot;666&quot; data-origin-height=&quot;558&quot; data-filename=&quot;edited_스크린샷 2023-04-22 09.45.09.png&quot; width=&quot;333&quot; height=&quot;279&quot; data-widthpercent=&quot;50.31&quot; style=&quot;width: 49.7266%;&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/JgvxD/btsbSMDNb0r/oNWrqoIInr4TtMoP0vJVVk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FJgvxD%2FbtsbSMDNb0r%2FoNWrqoIInr4TtMoP0vJVVk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;666&quot; height=&quot;558&quot;/&gt;&lt;/span&gt;&lt;/div&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&amp;nbsp;&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;2. createBrowserRouter&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2023-04-22 00.08.52.png&quot; data-origin-width=&quot;1382&quot; data-origin-height=&quot;320&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/zozNX/btsbTpg1OAF/2kGN2dw7bB1Jm5gIc8kPCK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/zozNX/btsbTpg1OAF/2kGN2dw7bB1Jm5gIc8kPCK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/zozNX/btsbTpg1OAF/2kGN2dw7bB1Jm5gIc8kPCK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FzozNX%2FbtsbTpg1OAF%2F2kGN2dw7bB1Jm5gIc8kPCK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;666&quot; height=&quot;154&quot; data-filename=&quot;스크린샷 2023-04-22 00.08.52.png&quot; data-origin-width=&quot;1382&quot; data-origin-height=&quot;320&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;createBrowserRouter는 React에서 브라우저의 URL을 사용하여 라우팅하는 컴포넌트이다. 이를 사용하면 URL 경로에 따른 컴포넌트를 렌더링할 수 있다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre class=&quot;javascript&quot;&gt;&lt;code&gt;//router.tsx

import { createBrowserRouter } from &quot;react-router-dom&quot;;
import Home from &quot;./Home&quot;;
import About from &quot;./About&quot;;

export const routers = createBrowserRouter([
  { path: &quot;/&quot;, element: &amp;lt;Home /&amp;gt; },
  { path: &quot;/about&quot;, element: &amp;lt;About /&amp;gt; },
]);&lt;/code&gt;&lt;/pre&gt;
&lt;pre class=&quot;coffeescript&quot;&gt;&lt;code&gt;// App.tsx

import { RouterProvider } from &quot;react-router-dom&quot;;
import { routers } from &quot;./router&quot;;

const App = () =&amp;gt; {
  return (
    &amp;lt;&amp;gt;
      &amp;lt;RouterProvider router={routers} /&amp;gt;
    &amp;lt;/&amp;gt;
  );
};

export default App;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;RouterProvider에는 props로 createBrowserRouter 함수로 생성한 router를 넣어줘야 한다. (위 예시는 router.tsx 파일을 따로 분리해서 createBrowserRouter 함수를 사용하여 router를 생성하였다.)&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;createBrowserRouter에는 라우팅할 path와 element를 작성해줘야 한다. (path와 element 속성 외에도 다양한 속성을 가지고 있다. )&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imagegridblock&quot;&gt;
  &lt;div class=&quot;image-container&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/SsyeB/btsbVbQetqD/GITNZA06Qz5UUCE8fR3Jw1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/SsyeB/btsbVbQetqD/GITNZA06Qz5UUCE8fR3Jw1/img.png&quot; data-is-animation=&quot;false&quot; data-origin-width=&quot;666&quot; data-origin-height=&quot;565&quot; data-filename=&quot;edited_스크린샷 2023-04-22 09.44.54.png&quot; width=&quot;333&quot; height=&quot;283&quot; data-widthpercent=&quot;49.69&quot; style=&quot;width: 49.1106%; margin-right: 10px;&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/SsyeB/btsbVbQetqD/GITNZA06Qz5UUCE8fR3Jw1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FSsyeB%2FbtsbVbQetqD%2FGITNZA06Qz5UUCE8fR3Jw1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;666&quot; height=&quot;565&quot;/&gt;&lt;/span&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bmvQpA/btsb1QY7QeS/bhreXSESrRgNW7bkHOnojk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bmvQpA/btsb1QY7QeS/bhreXSESrRgNW7bkHOnojk/img.png&quot; data-is-animation=&quot;false&quot; data-origin-width=&quot;666&quot; data-origin-height=&quot;558&quot; data-filename=&quot;edited_스크린샷 2023-04-22 09.45.09.png&quot; width=&quot;333&quot; height=&quot;279&quot; data-widthpercent=&quot;50.31&quot; style=&quot;width: 49.7266%;&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bmvQpA/btsb1QY7QeS/bhreXSESrRgNW7bkHOnojk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbmvQpA%2Fbtsb1QY7QeS%2FbhreXSESrRgNW7bkHOnojk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;666&quot; height=&quot;558&quot;/&gt;&lt;/span&gt;&lt;/div&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;결과적으로는 BrowserRouter를 사용한 것과 동일한 결과물을 얻을 수 있다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;참고&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;&lt;a href=&quot;https://reactrouter.com/en/main/start/overview&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://reactrouter.com/en/main/start/overview&lt;/a&gt; &amp;nbsp;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;&lt;a href=&quot;https://reactrouter.com/en/main/routers/create-browser-router&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://reactrouter.com/en/main/routers/create-browser-router&lt;/a&gt;&amp;nbsp; &amp;nbsp;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>React</category>
      <category>BrowserRouter</category>
      <category>createBrowserRouter</category>
      <category>React</category>
      <category>react router</category>
      <category>라우터</category>
      <category>리액트</category>
      <author>후끈후끈</author>
      <guid isPermaLink="true">https://likelacoste.tistory.com/69</guid>
      <comments>https://likelacoste.tistory.com/69#entry69comment</comments>
      <pubDate>Sat, 22 Apr 2023 09:49:39 +0900</pubDate>
    </item>
    <item>
      <title>[React] input의 value 가져오기</title>
      <link>https://likelacoste.tistory.com/68</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2023-04-15 09.37.16.png&quot; data-origin-width=&quot;1926&quot; data-origin-height=&quot;1636&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cD42ij/btsaVh4EpMA/nOYKO9dPTkeyN4M6k65B9k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cD42ij/btsaVh4EpMA/nOYKO9dPTkeyN4M6k65B9k/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cD42ij/btsaVh4EpMA/nOYKO9dPTkeyN4M6k65B9k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcD42ij%2FbtsaVh4EpMA%2FnOYKO9dPTkeyN4M6k65B9k%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;666&quot; height=&quot;566&quot; data-filename=&quot;스크린샷 2023-04-15 09.37.16.png&quot; data-origin-width=&quot;1926&quot; data-origin-height=&quot;1636&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;로그인 또는 회원가입 등과 같이 사용자로부터 필요한 정보를 받아야 할 때가 있다. 일반적으로 값을 받아올 때는 &lt;code&gt;input&lt;/code&gt; 요소를 사용한다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;React에서 input 요소를 이용하여 사용자로부터 값을 받아 사용할 수 있는 방법&lt;/b&gt;&lt;/span&gt;은 무엇이 있을까?&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;input의 값을 받아 사용하는 3가지 방법에 대해 알아보자.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;(아래의 예시는 React와 TypeScript, Styled-Component를 사용하였다.)&lt;/span&gt;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&amp;nbsp;&lt;/h2&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;1. useState을 이용하여 input의 value 가져오기&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;가장 쉽게 해볼 수 있는 것은 React Hook 중에 하나인 useState을 사용하여 input의 값을 상태로 관리하는 방법이다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;onChage.png&quot; data-origin-width=&quot;1278&quot; data-origin-height=&quot;1948&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bhKLCV/btsaTZ4hBcp/TmwecvN2cXYavnJn3ahn91/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bhKLCV/btsaTZ4hBcp/TmwecvN2cXYavnJn3ahn91/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bhKLCV/btsaTZ4hBcp/TmwecvN2cXYavnJn3ahn91/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbhKLCV%2FbtsaTZ4hBcp%2FTmwecvN2cXYavnJn3ahn91%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;666&quot; height=&quot;1015&quot; data-filename=&quot;onChage.png&quot; data-origin-width=&quot;1278&quot; data-origin-height=&quot;1948&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;먼저 useState을 사용하여 id와 password 변수를 선언한다. 그런 다음, &lt;code&gt;setId&lt;/code&gt;와 &lt;code&gt;setPassword&lt;/code&gt; 함수를 input의 &lt;code&gt;onChage&lt;/code&gt; 함수 안에 넣어 사용자가 값을 입력할 때마다 상태값이 바뀌면서 입력된 정보를 받아서 사용할 수 있다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;ezgif-4-56c53be3da.gif&quot; data-origin-width=&quot;600&quot; data-origin-height=&quot;375&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cBn7hu/btsaVetl5s1/V4wo5zLwOkF7QBRlBGc3Sk/img.gif&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cBn7hu/btsaVetl5s1/V4wo5zLwOkF7QBRlBGc3Sk/img.gif&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cBn7hu/btsaVetl5s1/V4wo5zLwOkF7QBRlBGc3Sk/img.gif&quot; srcset=&quot;https://blog.kakaocdn.net/dn/cBn7hu/btsaVetl5s1/V4wo5zLwOkF7QBRlBGc3Sk/img.gif&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;666&quot; height=&quot;416&quot; data-filename=&quot;ezgif-4-56c53be3da.gif&quot; data-origin-width=&quot;600&quot; data-origin-height=&quot;375&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;여기서 기억해야 하는 것은 &lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;리액트는 상태가 변할때마다 렌더링을 다시 한다는 것&lt;/b&gt;&lt;/span&gt;이다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;위에서 input에 값을 입력할 때마다 렌더링이 되고 있다는 것을 시각적으로 보여주고 있다. 사용자가 값을 입력할 때마다 onChage 이벤트가 발생하게 되면서 onChage 이벤트 핸들러 함수가 호출된다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2023-04-15 09.24.44.png&quot; data-origin-width=&quot;3014&quot; data-origin-height=&quot;1650&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/7UmJc/btsaTZiVke4/uTWpFrvnSrfZTKbMnMigwK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/7UmJc/btsaTZiVke4/uTWpFrvnSrfZTKbMnMigwK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/7UmJc/btsaTZiVke4/uTWpFrvnSrfZTKbMnMigwK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F7UmJc%2FbtsaTZiVke4%2FuTWpFrvnSrfZTKbMnMigwK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;666&quot; height=&quot;365&quot; data-filename=&quot;스크린샷 2023-04-15 09.24.44.png&quot; data-origin-width=&quot;3014&quot; data-origin-height=&quot;1650&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;우리는 onChage 이벤트가 발생할 때마다 상태의 값이 변경되도록 했기 때문에, 사용자가 input 요소에 값을 입력할 때마다 컴포넌트가 다시 렌더링이 되는 것이다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;2. useRef를 이용하여 input의 value 가져오기&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;useRef는 함수형 컴포넌트에서 DOM 노드나 다른 값을 저장하기 위해서 사용하는 React Hook이다. useRef를 사용하면 함수형 컴포넌트에서도 DOM 노드나 다른 값을 참조할 수 있게 되는데, useRef를 사용하면 &lt;code&gt;useRef()&lt;/code&gt; 함수를 호출하여 ref객체를 생성할 수 있고, 이 ref객체는 &lt;span style=&quot;background-color: #f6e199;&quot;&gt;&lt;b&gt;&amp;nbsp;.current&lt;/b&gt; &lt;/span&gt;라는 속성에 원하는 값을 할당할 수 있다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;useRef.png&quot; data-origin-width=&quot;1310&quot; data-origin-height=&quot;1876&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cGhWEn/btsaTgkJMBV/5L1z1NK7WKsrhudn3egs41/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cGhWEn/btsaTgkJMBV/5L1z1NK7WKsrhudn3egs41/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cGhWEn/btsaTgkJMBV/5L1z1NK7WKsrhudn3egs41/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcGhWEn%2FbtsaTgkJMBV%2F5L1z1NK7WKsrhudn3egs41%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;666&quot; height=&quot;954&quot; data-filename=&quot;useRef.png&quot; data-origin-width=&quot;1310&quot; data-origin-height=&quot;1876&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;먼저 useRef를 사용하여 input 요소의 값을 참조하는 userId와 userPassword 객체를 생성한 후, 생성한 객체를 input 요소의 ref 속성에 할당하게 되면 input 요소를 참조할 수 있게 된다. 그 다음 onSubmit 함수가 호출 될 때마다 userId, userPassword 객체의&amp;nbsp;&lt;b&gt;&lt;span style=&quot;background-color: #f6e199;&quot;&gt; .current &lt;/span&gt;&lt;/b&gt;&amp;nbsp;속성을 사용하여 사용자가 입력한 값을 가져와 사용할 수 있다.&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;ezgif-4-86e2eb2e2d.gif&quot; data-origin-width=&quot;600&quot; data-origin-height=&quot;375&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bOE2L4/btsaVez689W/XAv4bUKAuTiOO7jOU9YkZ0/img.gif&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bOE2L4/btsaVez689W/XAv4bUKAuTiOO7jOU9YkZ0/img.gif&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bOE2L4/btsaVez689W/XAv4bUKAuTiOO7jOU9YkZ0/img.gif&quot; srcset=&quot;https://blog.kakaocdn.net/dn/bOE2L4/btsaVez689W/XAv4bUKAuTiOO7jOU9YkZ0/img.gif&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;666&quot; height=&quot;416&quot; data-filename=&quot;ezgif-4-86e2eb2e2d.gif&quot; data-origin-width=&quot;600&quot; data-origin-height=&quot;375&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;일반적으로 Ref는 DOM 요소에 접근 할 때 사용한다. 그렇기 때문에 목적에 맞지 않게 무분별하게 사용하는 것은 좋지 않으니 주의해야 한다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;  참고 - Ref를 사용해야 할때&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;특정 input에 포커스 주기&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;스크롤 박스 조절하기&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;Canvas 요소에 그림 그리기 또는 media playback 등을 사용하기&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;3. FormData를 이용하여 input의 value 가져오기&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;FormData는 form 필드와 그 값을 key와 value로 쉽게 생성할 수 있는 객체이다. HTTP 요청의 일부로 데이터를 쉽게 구성하고 보낼 수 있고 데이터를 서버로 전송하기 위해 API와 함께 사용할 수 있다.&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;reasonml&quot;&gt;&lt;code&gt;let formData = new FormData([form])&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;HTML에 form 요소가 있는 경우, 위 코드와 같이 작성하면 해당 폼 요소의 필드 전체가 자동 반영되어 그 안에 있는 값을 key와 value로 가져올 수 있다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;FormData.png&quot; data-origin-width=&quot;1248&quot; data-origin-height=&quot;1408&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bd9fHC/btsaTZQJDni/6Sv7ILYQMKBj3G7mEajZM1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bd9fHC/btsaTZQJDni/6Sv7ILYQMKBj3G7mEajZM1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bd9fHC/btsaTZQJDni/6Sv7ILYQMKBj3G7mEajZM1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbd9fHC%2FbtsaTZQJDni%2F6Sv7ILYQMKBj3G7mEajZM1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;666&quot; height=&quot;751&quot; data-filename=&quot;FormData.png&quot; data-origin-width=&quot;1248&quot; data-origin-height=&quot;1408&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;onSubmit 함수를 form 요소의 onSubmit 이벤트가 발생할 때 실행되도록 만든다. 사용자가 아이디와 비밀번호를 입력한 후 onSubmit 이벤트를 발생시키면 사용자가 입력한 아이디와 비밀번호를 &lt;code&gt;useInfo&lt;/code&gt;라는 객체에 담아 사용할 수 있다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;ezgif-4-64a75b1daa.gif&quot; data-origin-width=&quot;600&quot; data-origin-height=&quot;375&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/xVOrJ/btsaVdVvSLh/KrdsjTvBbrKaXH8UwK1f20/img.gif&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/xVOrJ/btsaVdVvSLh/KrdsjTvBbrKaXH8UwK1f20/img.gif&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/xVOrJ/btsaVdVvSLh/KrdsjTvBbrKaXH8UwK1f20/img.gif&quot; srcset=&quot;https://blog.kakaocdn.net/dn/xVOrJ/btsaVdVvSLh/KrdsjTvBbrKaXH8UwK1f20/img.gif&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;666&quot; height=&quot;416&quot; data-filename=&quot;ezgif-4-64a75b1daa.gif&quot; data-origin-width=&quot;600&quot; data-origin-height=&quot;375&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;결론 &lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;프로젝트를 진행할 때 주로 useState을 사용하여 input의 값을 받아 상태로 관리하였다. (useRef를 사용하는 것은 사용 목적에 맞지 않기 때문에 필요한 상황이 아니면 사용하지 않았다.)&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;그런데 사용자로부터 받아야하는 정보가 많아지거나 또는 자식 컴포넌트가 많고 깊이가 깊어질 수록 값을 상태로 관리하는데 불편함이 있었다. (state을 자식 컴포넌트에게 porps로 내려줘야 하고 이에 따른 렌더링에 대해서도 고민해야 한다 ) 그러다가 공부를 하던 중 FormData를 사용하여 input의 값을 가져올 수 있는 방법에 대해 알게 되었고 사용해 본 결과 useSate을 사용하던 것 보다 간편하고 코드의 길이를 많이 줄일 수 있었다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;하지만 무조건 FormData를 사용하는 것이 맞는 방법은 아니고, 각각의 방법들은 다 장단점이 있다. 그렇기 때문에 무엇을 위해 사용해야하는지 그 목적을 분명하게 한 후, 목적에 맞게 사용하면 될 것 같다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;참고&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://ko.reactjs.org/docs/hooks-reference.html#usestate&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://ko.reactjs.org/docs/hooks-reference.html#usestate&lt;/a&gt; &amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://ko.reactjs.org/docs/hooks-reference.html#useref&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://ko.reactjs.org/docs/hooks-reference.html#useref&lt;/a&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://developer.mozilla.org/ko/docs/Web/API/FormData&quot;&gt;https://developer.mozilla.org/ko/docs/Web/API/FormData&lt;/a&gt;&lt;span&gt;&amp;nbsp; &amp;nbsp;&amp;nbsp; &amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://ko.javascript.info/formdata&quot;&gt;https://ko.javascript.info/formdata&lt;/a&gt;&amp;nbsp; &amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>React</category>
      <category>formData</category>
      <category>input value</category>
      <category>React</category>
      <category>useRef</category>
      <category>useState</category>
      <category>로그인</category>
      <category>리액트</category>
      <category>회원가입</category>
      <author>후끈후끈</author>
      <guid isPermaLink="true">https://likelacoste.tistory.com/68</guid>
      <comments>https://likelacoste.tistory.com/68#entry68comment</comments>
      <pubDate>Tue, 18 Apr 2023 12:11:58 +0900</pubDate>
    </item>
    <item>
      <title>Lighthouse를 이용한 성능 개선 - 이미지 최적화</title>
      <link>https://likelacoste.tistory.com/67</link>
      <description>&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2023-04-13 10.46.04.png&quot; data-origin-width=&quot;446&quot; data-origin-height=&quot;252&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/vbz4U/btsacflQWIs/Masdi0yYIk7Kpdh1WJ2lWK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/vbz4U/btsacflQWIs/Masdi0yYIk7Kpdh1WJ2lWK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/vbz4U/btsacflQWIs/Masdi0yYIk7Kpdh1WJ2lWK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fvbz4U%2FbtsacflQWIs%2FMasdi0yYIk7Kpdh1WJ2lWK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;446&quot; height=&quot;252&quot; data-filename=&quot;스크린샷 2023-04-13 10.46.04.png&quot; data-origin-width=&quot;446&quot; data-origin-height=&quot;252&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&amp;nbsp;&lt;/h2&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;비효율적인 이미지&lt;/span&gt;&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;Opportunities의 가장 첫 번째 항목인 &amp;lsquo;Properly size images&amp;rsquo;는 이미지를 적절한 사이즈로 사용도록 제안하고 있다. 안에 있는 내용을 보면 적절하지 않은 사이즈의 이미지를 적절한 사이즈로 변경하면 용량을 줄일 수 있다고 말한다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;브라우저에서 사용하는 이미지의 크기보다 큰 이미지가 페이지에 제공되면 바이트가 낭비되고 페이지 로드 시간이 느려진다. 그렇기 때문에 적절한 이미지의 크기를 제공하는 것은 중요하다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;자체적으로 가지고 있는 정적 이미지라면 사진 편집 프로그램을 이용하여 직접 이미지 사이즈를 조절하면 된다. 하지만 API를 통해 받아오는 경우에는 사진 편집을 직접 할 수는 없다. &lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;그렇다면 이미지 크기를 어떻게 줄일 수 있을까?&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;Image CDN&lt;/span&gt;&lt;/b&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;/span&gt;&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;CDN(Content Delivery Network)이란 물리적 거리의 한계를 극복하기 위해 사용자와 가까운 곳에 콘텐츠 서버를 두는 기술을 말하는데, Image CDN은 이미지에 특화된 CDN이라고 할 수 있다. 기본적인 CDN기능과 더불어 이미지를 사용자에게 보내기 전에 특정 형태로 가공(사이즈, 포맷 변경 등)하여 전해줄 수 있다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;ex) http://cdn.image.com?src=[img src]&amp;amp;width=120&amp;amp;height=120&lt;/b&gt;&lt;/span&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;- 변경하고자 하는 형태(width, height)를 명시해줄 수 있다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;이미지 최적화&lt;/span&gt;&lt;/b&gt;&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;123123.png&quot; data-origin-width=&quot;1190&quot; data-origin-height=&quot;1120&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/czQ3XM/btr94jCGerA/4OtSoTxFLNbKkDOnASTPt0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/czQ3XM/btr94jCGerA/4OtSoTxFLNbKkDOnASTPt0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/czQ3XM/btr94jCGerA/4OtSoTxFLNbKkDOnASTPt0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FczQ3XM%2Fbtr94jCGerA%2F4OtSoTxFLNbKkDOnASTPt0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;666&quot; height=&quot;627&quot; data-filename=&quot;123123.png&quot; data-origin-width=&quot;1190&quot; data-origin-height=&quot;1120&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;getParametersForUnsplash 함수를 만들 이미지 태그에 전달해서 이미지의 크기를 변경해주었다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&amp;nbsp;&lt;/h2&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;성능 개선 결과 &lt;/span&gt;&lt;/b&gt;&lt;/h2&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2023-04-13 11.21.45.png&quot; data-origin-width=&quot;1062&quot; data-origin-height=&quot;688&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bzJzUt/btr92pQWz4f/VbLeUacRv2n14M6Q3ypAok/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bzJzUt/btr92pQWz4f/VbLeUacRv2n14M6Q3ypAok/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bzJzUt/btr92pQWz4f/VbLeUacRv2n14M6Q3ypAok/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbzJzUt%2Fbtr92pQWz4f%2FVbLeUacRv2n14M6Q3ypAok%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;666&quot; height=&quot;431&quot; data-filename=&quot;스크린샷 2023-04-13 11.21.45.png&quot; data-origin-width=&quot;1062&quot; data-origin-height=&quot;688&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;기존 50점이 였던 Performance가 90점으로 향상 된 것을 볼 수 있었다.(사용하는 이미지의 수가 많아서 성능의 큰 영향을 주고 있었구나&amp;hellip;.&lt;span&gt; &lt;/span&gt;)&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;정적인 이미지의 크기와 URL의 쿼리스트링을 통한 이미지 크기를 변경해 줌으로써 화면이 렌더링 되는 속도가 이전보다 확실하게 빨라지는 것을 볼 수 있었다. 평소 1초 2초라는 시간은 순간일 수 있을지 모르지만 웹 어플리케이션을 사용하는 사람에게는 불편함을 느낄 수 있는 시간이다. 그렇기 때문에 성능을 개선하는 것은 무조건적으로 필요하며 개선하기 위해 어떻게 해야하는지를 계속해서 고민하는 자세가 필요하나는 것을 다시 한 번 생각해 볼 수 있었다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;참고&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.aladin.co.kr/shop/wproduct.aspx?ItemId=304371832&quot;&gt;https://www.aladin.co.kr/shop/wproduct.aspx?ItemId=304371832&lt;/a&gt;&lt;span style=&quot;background-color: #ffffff; color: #000000; text-align: left;&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;</description>
      <category>개발이야기</category>
      <category>CDN</category>
      <category>Lighthouse</category>
      <category>개발이야기</category>
      <category>성능최적화</category>
      <category>프론트엔드</category>
      <author>후끈후끈</author>
      <guid isPermaLink="true">https://likelacoste.tistory.com/67</guid>
      <comments>https://likelacoste.tistory.com/67#entry67comment</comments>
      <pubDate>Fri, 14 Apr 2023 11:30:16 +0900</pubDate>
    </item>
    <item>
      <title>Lighthouse를 이용한 성능 개선 - 번들링 개선</title>
      <link>https://likelacoste.tistory.com/66</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;이전에 진행했던 프로젝트를 다시 실행해봤는데 화면이 나타날 때까지의 시간이 오래 걸리는 것을 보고 성능 개선을 해봐야겠다는 생각이 들었다. 제일 먼저 간단하게 Lighthouse를 사용하여 화면의 성능을 측정해 보았다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;Lighthouse란?&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;Lighthouse는 구글에서 만들 틀로, 웹사이트의 성능을 측정하고 개선 방향을 제시해 주는 자동화 틀이다. Lighthouse를 이용하면 웹사이트의 성능 점수를 측정하고 개선 가이드를 확인함으로써 어떤 부분을 중점적으로 최적화해야 하는지에 대해 알 수 있다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2023-04-12 13.35.51.png&quot; data-origin-width=&quot;941&quot; data-origin-height=&quot;682&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/enya1N/btr9Ozx8B1X/fUNNCtYSoIepcgx3Z36DBK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/enya1N/btr9Ozx8B1X/fUNNCtYSoIepcgx3Z36DBK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/enya1N/btr9Ozx8B1X/fUNNCtYSoIepcgx3Z36DBK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fenya1N%2Fbtr9Ozx8B1X%2FfUNNCtYSoIepcgx3Z36DBK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;666&quot; height=&quot;483&quot; data-filename=&quot;스크린샷 2023-04-12 13.35.51.png&quot; data-origin-width=&quot;941&quot; data-origin-height=&quot;682&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;Performance 점수가 36점&amp;hellip; 왜 이렇게 낮을까?&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2023-04-12 14.00.51.png&quot; data-origin-width=&quot;938&quot; data-origin-height=&quot;307&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/7lBOW/btr9N1aB33i/W9VkavC0bxE1g1dnzgekS0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/7lBOW/btr9N1aB33i/W9VkavC0bxE1g1dnzgekS0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/7lBOW/btr9N1aB33i/W9VkavC0bxE1g1dnzgekS0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F7lBOW%2Fbtr9N1aB33i%2FW9VkavC0bxE1g1dnzgekS0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;666&quot; height=&quot;218&quot; data-filename=&quot;스크린샷 2023-04-12 14.00.51.png&quot; data-origin-width=&quot;938&quot; data-origin-height=&quot;307&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;개선해야 할 점을 보면 사용하지 않은 자바스크립트의 파일을 줄이라고 나와있다. 그리고 가장 위의 용량이 큰 파일을 보면 bundle.js라고 되어 있는데 이건 뭘까?&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;Bundle?&lt;/span&gt;&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;번들링이란 사용자에게 웹 어플리케이션을 제공하기 위해 여러 코드와 프로그램을 묶는 것을 말한다. 개발자는 최종적으로 번들링된 웹 어플리케이션을 만들고, 사용자가 웹 어프리케이션을 이용할 때는 번들링한 파일을 서버로부터 받아서 브라우저가 이 번들을 실행한다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;create-react-app으로 시작하는 경우, 기본적으로 Webpack 및 Babel이 설정 되어 있는데 번들링을 하게 되면 모든 자바스크립트 파일이 하나의 자바스크립트 파일(bundle.js)로 합쳐지게 된다. 번들된 파일은 프로젝트의 크기가 커질 수록 용량이 커지며, 처음 페이지에 접근할 때 자바스크립트의 파일을 불러오는 Client-Server-Landering의 특성 상 시간이 오래 걸리는 문제가 발생할 수 있다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;React 공식 홈페이지에서는 이러한 문제를 개선할 수 있는 방법으로 &lt;span style=&quot;color: #f89009;&quot;&gt;&lt;b&gt;&lt;a style=&quot;color: #f89009;&quot; title=&quot;코드 분할(Code Splitting)&quot; href=&quot;https://ko.reactjs.org/docs/code-splitting.html&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;코드 분할(Code Splitting)&lt;/a&gt;&lt;/b&gt;&lt;/span&gt;을 제시하고 있다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;코드분할(Code Splitting)&lt;/span&gt;&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;코드분할을 이용하면 페이지별로 코드를 분할하는 것으로 하나의 번들 파일을 여러 개의 파일로 쪼개는 방법이다. 분할된 코드는 사용자가 서비스를 이용하는 중에 해당 코드가 필요해지는 시점에 로드되어 실행되는데, 이를 지연 로딩이라고 한다. (필요 없는 코드를 다운로드 하지 않으니 로드 속도는 빨라지게 된다.)&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;lazy와 Suspense 함수를 사용하여 동적 import를 할 수 있다.&lt;/b&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;Before&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;clean&quot;&gt;&lt;code&gt;import OtherComponent from './OtherComponent';&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;After&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;coffeescript&quot;&gt;&lt;code&gt;const OtherComponent = React.lazy(() =&amp;gt; import('./OtherComponent'));&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;lazy 컴포넌트는 Suspense 컴포넌트 하위에 렌더링되어야 하며, Suspense는 lazy 컴포넌트가 로드 되기를 기다리는 동안 로딩 화면과 같은 컨테츠를 보여줄 수 있다.&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;javascript&quot;&gt;&lt;code&gt;import React, { Suspense } from 'react';

const OtherComponent = React.lazy(() =&amp;gt; import('./OtherComponent'));

function MyComponent() {
  return (
    &amp;lt;div&amp;gt;
      &amp;lt;Suspense fallback={&amp;lt;div&amp;gt;Loading...&amp;lt;/div&amp;gt;}&amp;gt;
        &amp;lt;OtherComponent /&amp;gt;
      &amp;lt;/Suspense&amp;gt;
    &amp;lt;/div&amp;gt;
  );
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;이렇게 해서 코드 분할을 진행해보니 번들 사이즈가 거의 절반으로 줄어든 것을 볼 수 있었다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;react-icons&lt;/span&gt;&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;아이콘을 사용하기 위해서 react-icons라는 라이브러리를 사용하였는데, 사용한 아이콘의 수 보다 라이브러리의 chunck 사이즈가 크다는 것을 알 수 있었다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;react-icons는 아이콘의 종류별로 구분되어 있고 종류별로 하나의 js 파일에 아이콘 전체를 포함하고 있는데, 이 때문에 아이콘 하나만 가져오려고 해도 해당 아이콘을 담고 있는 전체 파일을 사용하기 때문에 성능 문제가 발생하게 된다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;그래서 찾아보니 react-icons에서 &lt;code&gt;@react-icons/all-files&lt;/code&gt;라는 별도의 라이브러릴 제공하는데, 해당 라이브러리는 아이콘 별로 자바스크립트 파일을 별도로 가지고 있어 빌드 시 트리 쉐이킹 방식으로 더 적은 크기의 chunk를 만들 수 있다고 한다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;Before&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;capnproto&quot;&gt;&lt;code&gt;import { FaBeer } from &quot;react-icons/fa&quot;;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;After&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;nginx&quot;&gt;&lt;code&gt;import { FaBeer } from &quot;@react-icons/all-files/fa/FaBeer&quot;;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;  성능 개선 결과&lt;/span&gt;&lt;/b&gt;&lt;/h2&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2023-04-13 10.37.36.png&quot; data-origin-width=&quot;1078&quot; data-origin-height=&quot;697&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/do7tNw/btr9P3teKcf/me1JRv10kFHCqLb3JxIoZ1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/do7tNw/btr9P3teKcf/me1JRv10kFHCqLb3JxIoZ1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/do7tNw/btr9P3teKcf/me1JRv10kFHCqLb3JxIoZ1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fdo7tNw%2Fbtr9P3teKcf%2Fme1JRv10kFHCqLb3JxIoZ1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;666&quot; height=&quot;431&quot; data-filename=&quot;스크린샷 2023-04-13 10.37.36.png&quot; data-origin-width=&quot;1078&quot; data-origin-height=&quot;697&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;기존 36점이였던 Performance 점수가 50점으로 상승한 것을 볼 수 있었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2023-04-12 15.05.08.png&quot; data-origin-width=&quot;825&quot; data-origin-height=&quot;86&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/BE1c3/btr9Nn6glG6/ur2CmrOWKSnjeKGVaakWF0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/BE1c3/btr9Nn6glG6/ur2CmrOWKSnjeKGVaakWF0/img.png&quot; data-alt=&quot;성능 개선 이전&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/BE1c3/btr9Nn6glG6/ur2CmrOWKSnjeKGVaakWF0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FBE1c3%2Fbtr9Nn6glG6%2Fur2CmrOWKSnjeKGVaakWF0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;666&quot; height=&quot;69&quot; data-filename=&quot;스크린샷 2023-04-12 15.05.08.png&quot; data-origin-width=&quot;825&quot; data-origin-height=&quot;86&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;성능 개선 이전&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2023-04-12 15.05.18.png&quot; data-origin-width=&quot;918&quot; data-origin-height=&quot;115&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/euveAF/btr9DURstNT/HtvEd1hHRgw3bdUOu0WlXk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/euveAF/btr9DURstNT/HtvEd1hHRgw3bdUOu0WlXk/img.png&quot; data-alt=&quot;성능 개선 이후&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/euveAF/btr9DURstNT/HtvEd1hHRgw3bdUOu0WlXk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FeuveAF%2Fbtr9DURstNT%2FHtvEd1hHRgw3bdUOu0WlXk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;666&quot; height=&quot;83&quot; data-filename=&quot;스크린샷 2023-04-12 15.05.18.png&quot; data-origin-width=&quot;918&quot; data-origin-height=&quot;115&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;성능 개선 이후&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아직까지 낮은 점수를 가지고 있는데 나머지 문제점도 해결해봐야겠다. &lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;참고&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.aladin.co.kr/shop/wproduct.aspx?ItemId=304371832&quot;&gt;https://www.aladin.co.kr/shop/wproduct.aspx?ItemId=304371832&lt;/a&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://ko.reactjs.org/docs/code-splitting.html&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://ko.reactjs.org/docs/code-splitting.html&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://eratosthenes.tistory.com/2&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://eratosthenes.tistory.com/2&amp;nbsp;&lt;/a&gt;&lt;/p&gt;</description>
      <category>개발이야기</category>
      <category>Lighthouse</category>
      <category>개발이야기</category>
      <category>성능 최적화</category>
      <category>코드분할</category>
      <category>프론트엔드</category>
      <author>후끈후끈</author>
      <guid isPermaLink="true">https://likelacoste.tistory.com/66</guid>
      <comments>https://likelacoste.tistory.com/66#entry66comment</comments>
      <pubDate>Wed, 12 Apr 2023 15:23:00 +0900</pubDate>
    </item>
    <item>
      <title>6. 인터페이스</title>
      <link>https://likelacoste.tistory.com/65</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;타입 별칭과 인터페이스&lt;/span&gt;&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;아래 코드는 &lt;code&gt;name: string&lt;/code&gt;과 &lt;code&gt;age: number&lt;/code&gt;를 가진 객체를 타입 별칭과 인터페이스로 구현한 구문입니다.&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;routeros&quot;&gt;&lt;code&gt;type Person = {
    name: string;
    age: number;
}

interface Person{
    name: string;
    age: number;
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;두 구문에 대한 타입스크립트의 할당 가능성 검사와 오류 메시지는 거의 동일합니다. 하지만 완전하게 동일하지 않고 몇 가지 차이점을 가지고 있습니다.&lt;/span&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;인터페이스는 속성 증가를 위해 병합 할 수 있습니다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;인터페이스는 클래스가 선언된 구조의 타입을 확인하는데 사용할 수 있지만, 타입 별칭은 사용할 수 없습니다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;일반적으로 인터페이스의 타입 검사가 더 빠릅니다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;인터페이스는 이름 없는 객체 리터럴의 별칭이 아닌 이름이 있는 객체로 간주되어, 어려운 특이한 케이스에서 나타나는 오류 메시지를 좀 더 쉽게 볼 수 있습니다.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&amp;nbsp;&lt;/h2&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;속성 타입&lt;/span&gt;&lt;/b&gt;&lt;/h2&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;1. 선택적 속성&lt;/span&gt;&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;인터페이스의 속성이 필수가 아닌 경우 &lt;code&gt;:&lt;/code&gt; 앞에 &lt;code&gt;?&lt;/code&gt;를 사용하여 해당 속성이 선택적인 속성임을 나타낼 수 있습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2023-02-27 23.13.29.png&quot; data-origin-width=&quot;444&quot; data-origin-height=&quot;572&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/lCFwq/btr1Mi0xXLS/3DyDotAQGT6HnXe80oplAk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/lCFwq/btr1Mi0xXLS/3DyDotAQGT6HnXe80oplAk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/lCFwq/btr1Mi0xXLS/3DyDotAQGT6HnXe80oplAk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FlCFwq%2Fbtr1Mi0xXLS%2F3DyDotAQGT6HnXe80oplAk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;444&quot; height=&quot;572&quot; data-filename=&quot;스크린샷 2023-02-27 23.13.29.png&quot; data-origin-width=&quot;444&quot; data-origin-height=&quot;572&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&amp;nbsp;&lt;/h4&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;2. 읽기 전용 속성&lt;/span&gt;&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;인터페이스에 정의된 객체의 속성을 재할당하지 못하도록 하고 싶은 경우 &lt;code&gt;readonly&lt;/code&gt; 키워드를 사용하여 사용자를 차단할 수 있습니다. 객체의 속성 이름 앞에 &lt;code&gt;readonly&lt;/code&gt; 키워드를 사용하면 해당 속성은 평소대로 읽을 수 있지만 &lt;b&gt;새로운 값으로 재할당 하지 못합니다.&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2023-02-27 23.25.13.png&quot; data-origin-width=&quot;1098&quot; data-origin-height=&quot;460&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bNuSxC/btr1YKg0K0K/yPKacan9yZVXuAwfjKcLk0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bNuSxC/btr1YKg0K0K/yPKacan9yZVXuAwfjKcLk0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bNuSxC/btr1YKg0K0K/yPKacan9yZVXuAwfjKcLk0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbNuSxC%2Fbtr1YKg0K0K%2FyPKacan9yZVXuAwfjKcLk0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;666&quot; height=&quot;279&quot; data-filename=&quot;스크린샷 2023-02-27 23.25.13.png&quot; data-origin-width=&quot;1098&quot; data-origin-height=&quot;460&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;주의해야하는 점은 &lt;code&gt;readonly&lt;/code&gt;는 단지 타입스크립트 타입 검사기를 사용해 개발 중에 그 속성이 수정되지 못하도록 보호하는 역할을 하는 &lt;b&gt;타입 시스템의 구성 요소&lt;/b&gt;라는 것입니다. (컴파일된 자바스크립트가 실행하는 것을 막아주지는 못함)&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;3. 함수와 메서드&lt;/span&gt;&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;타입스크립트에서 함수를 선언하는 방법은 두 가지가 있었습니다.&lt;/span&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;메서드 구문: &lt;code&gt;member(): void&lt;/code&gt; 와 같이 객체의 맴버로 호출되는 함수로 선언&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;속성 구문: &lt;code&gt;member: () &amp;rArr; void&lt;/code&gt; 와 같이 독립 함수와 동일하게 선언&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;두 가지 선언 방법은 인터페이스에서 동일하게 사용할 수 있습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2023-03-04 21.08.12.png&quot; data-origin-width=&quot;720&quot; data-origin-height=&quot;569&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bsAzL3/btr1Qx4g0lo/dmFNgbJ3MLxJetLiMSX5r0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bsAzL3/btr1Qx4g0lo/dmFNgbJ3MLxJetLiMSX5r0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bsAzL3/btr1Qx4g0lo/dmFNgbJ3MLxJetLiMSX5r0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbsAzL3%2Fbtr1Qx4g0lo%2FdmFNgbJ3MLxJetLiMSX5r0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;666&quot; height=&quot;526&quot; data-filename=&quot;스크린샷 2023-03-04 21.08.12.png&quot; data-origin-width=&quot;720&quot; data-origin-height=&quot;569&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;메서드와 속성 선언은 대부분 서로 교환해서 사용할 수 있지만, 몇 가지 차이점이 있습니다.&lt;/span&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;메서드 구문에서는 &lt;code&gt;readonly&lt;/code&gt;로 선언할 수 없지만, 속성 구문은 사용할 수 있습니다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;인터페이스 병합은 메서드 구문과 속성 구문을 다르게 처리합니다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;타입에서 수행되는 일부 작업은 메서드 구문과 속성 구문을 다르게 처리합니다.&lt;/span&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt;&lt;b&gt;❗️ 메서드 구문과 속성 구문 사용 가이드&lt;/b&gt;&lt;br /&gt;- 기본 함수가 this를 참조할 수 있다는 것을 알고 있다면 메서드 함수를 사용(클래스의 인스턴스)&lt;br /&gt;- 반대의 경우에는 속성 함수를 사용&lt;/blockquote&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&amp;nbsp;&lt;/h4&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;4. 인덱스 시그니처(index signature)&lt;/span&gt;&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;종종 자바스크립트 프로젝트에서 임의의 string 키에 값을 저장하기 위한 객체를 사용하는 경우가 있습니다. 이러한 컨테이너(container) 객체의 경우 모든 가능한 키에 대해 필드가 있는 인터페이스를 선언한다는 것은 비현실적이거나 불가능합니다. 타입스크립트에서는 인덱스 시그니처 구문을 제공하여 인터페이스의 객체가 임의의 키를 받고, 해당 키 아래의 특정 타입을 반환할 수 있음을 나타낼 수 있습니다.&lt;/span&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;code&gt;{[i: string]: &amp;hellip; }&lt;/code&gt;&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2023-03-04 21.27.17.png&quot; data-origin-width=&quot;828&quot; data-origin-height=&quot;465&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cceC9j/btr16jQF0O3/VFRjdTUaSRgT6RUxmTpmfk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cceC9j/btr16jQF0O3/VFRjdTUaSRgT6RUxmTpmfk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cceC9j/btr16jQF0O3/VFRjdTUaSRgT6RUxmTpmfk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcceC9j%2Fbtr16jQF0O3%2FVFRjdTUaSRgT6RUxmTpmfk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;666&quot; height=&quot;374&quot; data-filename=&quot;스크린샷 2023-03-04 21.27.17.png&quot; data-origin-width=&quot;828&quot; data-origin-height=&quot;465&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;인덱스 시그니처는 객체에 값을 할당할 때 편리하지만, 타입의 안정성을 완벽하게 보장하지 못합니다. &lt;b&gt;인덱스 시그니처는 객체가 어떤 속성에 접근하든 간에 &lt;span style=&quot;color: #ee2323;&quot;&gt;값을 반환&lt;/span&gt;해야 합니다.&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2023-03-04 21.36.21.png&quot; data-origin-width=&quot;1256&quot; data-origin-height=&quot;406&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/diktkU/btr1KxjnG7e/6U2N9cQdGrYjDHbPoHOFKk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/diktkU/btr1KxjnG7e/6U2N9cQdGrYjDHbPoHOFKk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/diktkU/btr1KxjnG7e/6U2N9cQdGrYjDHbPoHOFKk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdiktkU%2Fbtr1KxjnG7e%2F6U2N9cQdGrYjDHbPoHOFKk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;666&quot; height=&quot;215&quot; data-filename=&quot;스크린샷 2023-03-04 21.36.21.png&quot; data-origin-width=&quot;1256&quot; data-origin-height=&quot;406&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;타입스크립트는 birthday의 모든 속성의 값은 Date 타입으로 안전한게 반환하지만, 실제로 mother의 값이 정의되지 않았음에도 불구하고 정의되었다고 판단하여 타입에러가 발생하지 않는 것을 볼 수 있습니다.(자바스크립트 런타임에서는 오류가 발생함)&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt;❗️ Tip&lt;br /&gt;- 키/값 쌍을 저장하려고 하는데 키를 미리 알 수 없다면 &lt;u&gt;&lt;b&gt;Map&lt;/b&gt;&lt;/u&gt;을 사용하는 편이 더 안전하다.&lt;br /&gt;- &lt;u&gt;&lt;b&gt;.get&lt;/b&gt;&lt;/u&gt; 메서드는 항상 키가 존재하지 않음을 나타내기 위해서 &lt;u&gt;&lt;b&gt;| undefined&lt;/b&gt; &lt;/u&gt;타입을 반환합니다.&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;인터페이스는 명시적으로 명명된 속성과 포괄적인 용도의 string 인덱스 시그니처를 한번에 포함해서 사용할 수 있습니다. 명명된 속성은 더 구체적인 타입을 제공하고, 다른 모든 속성은 인덱스 시그니처의 타입으로 대체하는 것으로 혼합해서 사용할 수 있습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2023-03-04 21.53.47.png&quot; data-origin-width=&quot;896&quot; data-origin-height=&quot;576&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/IvQk3/btr1XOX5b3P/HwRvkNDZWIB8NPJveTSJq0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/IvQk3/btr1XOX5b3P/HwRvkNDZWIB8NPJveTSJq0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/IvQk3/btr1XOX5b3P/HwRvkNDZWIB8NPJveTSJq0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FIvQk3%2Fbtr1XOX5b3P%2FHwRvkNDZWIB8NPJveTSJq0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;666&quot; height=&quot;428&quot; data-filename=&quot;스크린샷 2023-03-04 21.53.47.png&quot; data-origin-width=&quot;896&quot; data-origin-height=&quot;576&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;타입 시그니처의 키의 타입을 &lt;u&gt;&lt;b&gt;string&lt;/b&gt;&lt;/u&gt;뿐만 아니라 &lt;u&gt;&lt;b&gt;number&lt;/b&gt;&lt;/u&gt; 타입을 사용할 수도 있습니다. 하지만 주의해야하는 점은 해당 키의 값에 대한 타입은 포괄적인 용도의 &lt;u&gt;&lt;b&gt;string&lt;/b&gt;&lt;/u&gt; 인덱스 시그니처의 타입을 할당해야 합니다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2023-03-04 22.06.25.png&quot; data-origin-width=&quot;815&quot; data-origin-height=&quot;586&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/r202y/btr1XxI0cP2/wYhk9IfOO1iEOD5yeDKG2K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/r202y/btr1XxI0cP2/wYhk9IfOO1iEOD5yeDKG2K/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/r202y/btr1XxI0cP2/wYhk9IfOO1iEOD5yeDKG2K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fr202y%2Fbtr1XxI0cP2%2FwYhk9IfOO1iEOD5yeDKG2K%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;666&quot; height=&quot;479&quot; data-filename=&quot;스크린샷 2023-03-04 22.06.25.png&quot; data-origin-width=&quot;815&quot; data-origin-height=&quot;586&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&amp;nbsp;&lt;/h3&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;인터페이스 확장(Interface Extend)&lt;/span&gt;&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;때로는 형태가 비슷한 여러 개의 인터페이스를 갖게 되는 경우도 있습니다. 예를 들어 다른 인터페이스의 모든 멤버를 포함하고, 거기에 몇 개의 맴버가 추가되는 인터페이스의 경우입니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;타입스크립트는 인터페이스가 다른 인터페이스의 모든 멤버를 복사해서 선언할 수 있는 확장된 인터페이스를 허용합니다. 확장할 인터페이스의 이름 뒤에 &lt;code&gt;extends&lt;/code&gt; 키워드를 추가해서 다른 인터페이스를 확장한 인터페이스라는 걸 표시하여 사용합니다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2023-03-04 22.16.04.png&quot; data-origin-width=&quot;900&quot; data-origin-height=&quot;614&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Mb0Sk/btr115kTsTm/Ib7hT2jZebbw93Z1m4p5Kk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Mb0Sk/btr115kTsTm/Ib7hT2jZebbw93Z1m4p5Kk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Mb0Sk/btr115kTsTm/Ib7hT2jZebbw93Z1m4p5Kk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FMb0Sk%2Fbtr115kTsTm%2FIb7hT2jZebbw93Z1m4p5Kk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;666&quot; height=&quot;454&quot; data-filename=&quot;스크린샷 2023-03-04 22.16.04.png&quot; data-origin-width=&quot;900&quot; data-origin-height=&quot;614&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;인터페이스 확장은 프로젝트의 한 엔티티(entity) 타입이 다른 엔티티의 모든 멤버를 포함하는 상위 집합(superset)을 나타내는 실용적인 방법입니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;파생 인터페이스는 다른 타입으로 속성을 다시 선언해 기본 인터페이스의 속성을 재정의(override)하거나 대체할 수 있습니다. 중요한 것은 재정의된 속성은 기본 속성에 할당되어 있어야 합니다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2023-03-04 22.33.13.png&quot; data-origin-width=&quot;1227&quot; data-origin-height=&quot;612&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cVySuJ/btr1UUkflug/mcms8xOheC6ySWJ7kF2hck/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cVySuJ/btr1UUkflug/mcms8xOheC6ySWJ7kF2hck/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cVySuJ/btr1UUkflug/mcms8xOheC6ySWJ7kF2hck/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcVySuJ%2Fbtr1UUkflug%2Fmcms8xOheC6ySWJ7kF2hck%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;666&quot; height=&quot;332&quot; data-filename=&quot;스크린샷 2023-03-04 22.33.13.png&quot; data-origin-width=&quot;1227&quot; data-origin-height=&quot;612&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;❗️ &lt;b&gt;속성을 재선언하는 대부분의 파상 인터페이스는 해당 속성을 유니언 타입의 더 구체적인 하위 집합으로 만들거나 속성을 기본 인터페이스의 타엡에서 확장된 타입으로 만들기 위해 사용됩니다.&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;타입 확장은 쉼표(,)를 사용하여 여러 개의 다른 인터페이스를 확장해서 선언할 수 있습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2023-03-04 22.38.36.png&quot; data-origin-width=&quot;868&quot; data-origin-height=&quot;583&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cUMvj3/btr1UUkflRN/3qzn6gWmpkrWySHnwxEikk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cUMvj3/btr1UUkflRN/3qzn6gWmpkrWySHnwxEikk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cUMvj3/btr1UUkflRN/3qzn6gWmpkrWySHnwxEikk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcUMvj3%2Fbtr1UUkflRN%2F3qzn6gWmpkrWySHnwxEikk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;666&quot; height=&quot;447&quot; data-filename=&quot;스크린샷 2023-03-04 22.38.36.png&quot; data-origin-width=&quot;868&quot; data-origin-height=&quot;583&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;여러 인터페이스를 확장하는 방식을 사용하면 코드 중복을 줄이고 다른 코드 영역에서 객체의 형태를 더 쉽게 재사용할 수 있습니다.&lt;/span&gt;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&amp;nbsp;&lt;/h3&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;인터페이스 병합&lt;/span&gt;&lt;/b&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;인터페이스의 중요한 특징 중 하나는 서로 병합하는 능력입니다. &lt;b&gt;두 개의 인터페이스가 동일한 이름으로 동일한 스코프에 선언된 경우&lt;/b&gt;, 선언된 모든 필드를 포함하는 더 큰 인터페이스가 코드에 추가됩니다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2023-03-04 22.43.48.png&quot; data-origin-width=&quot;545&quot; data-origin-height=&quot;429&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dqvm2O/btr133Aq1k2/ef0bU0ueKcTxVDbkOoRKQK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dqvm2O/btr133Aq1k2/ef0bU0ueKcTxVDbkOoRKQK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dqvm2O/btr133Aq1k2/ef0bU0ueKcTxVDbkOoRKQK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fdqvm2O%2Fbtr133Aq1k2%2Fef0bU0ueKcTxVDbkOoRKQK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;444&quot; height=&quot;349&quot; data-filename=&quot;스크린샷 2023-03-04 22.43.48.png&quot; data-origin-width=&quot;545&quot; data-origin-height=&quot;429&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;인터페이스가 여러 곳에 선언되면 코드의 가독성이 떨어지기 때문에 가능하면 인터페이스 병합을 사용하지 않는 것이 좋습니다. 그러나 외부 패키지 또는 Window 같은 내장된 전역 인터페이스를 보강하는데 사용하면 유용하게 사용할 수 있습니다.&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;angelscript&quot;&gt;&lt;code&gt;interface Window{
    myEnvironmentVariable: string;
}

window.myEnvironmentVariable; // 타입: string&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;주의해야하는 점은 인터페이스 타입이 다른 동일한 이름의 속성을 여러 번 선언할 수 없다는 것입니다. 속성이 이미 인터페이스에 선언되어 있다면 나중에 병합된 인터페이스에도 동일한 타입을 사용해야 합니다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2023-03-04 22.51.47.png&quot; data-origin-width=&quot;985&quot; data-origin-height=&quot;427&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bd1Hmr/btr133NWpsp/GA1dcauxlKRLhx9Uhc9fKk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bd1Hmr/btr133NWpsp/GA1dcauxlKRLhx9Uhc9fKk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bd1Hmr/btr133NWpsp/GA1dcauxlKRLhx9Uhc9fKk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbd1Hmr%2Fbtr133NWpsp%2FGA1dcauxlKRLhx9Uhc9fKk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;666&quot; height=&quot;289&quot; data-filename=&quot;스크린샷 2023-03-04 22.51.47.png&quot; data-origin-width=&quot;985&quot; data-origin-height=&quot;427&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.aladin.co.kr/shop/wproduct.aspx?ItemId=307683870&quot;&gt;https://www.aladin.co.kr/shop/wproduct.aspx?ItemId=307683870&lt;/a&gt;&lt;span style=&quot;background-color: #ffffff; color: #000000;&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1677938995562&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;books.book&quot; data-og-title=&quot;러닝 타입스크립트&quot; data-og-description=&quot;자바스크립트 세계를 정복한 타입스크립트는 강력한 타입 안정성에 힘입어 가장 빠르게 성장하고 있다. 언어의 역사를 살펴보며 진화 과정과 작동 방식을 이해하고, 개념 설명을 돕는 수많은 &quot; data-og-host=&quot;www.aladin.co.kr&quot; data-og-source-url=&quot;https://www.aladin.co.kr/shop/wproduct.aspx?ItemId=307683870&quot; data-og-url=&quot;https://www.aladin.co.kr/shop/wproduct.aspx?ItemId=307683870&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/mLO9b/hyROWymZuv/sSMIDKmg2JFz0KEFUaWSq1/img.jpg?width=500&amp;amp;height=642&amp;amp;face=0_0_500_642,https://scrap.kakaocdn.net/dn/bqh6X2/hyRQxqbVsE/OWSJln6zhrdOmMkGA4RBvk/img.jpg?width=500&amp;amp;height=642&amp;amp;face=0_0_500_642&quot;&gt;&lt;a href=&quot;https://www.aladin.co.kr/shop/wproduct.aspx?ItemId=307683870&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://www.aladin.co.kr/shop/wproduct.aspx?ItemId=307683870&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/mLO9b/hyROWymZuv/sSMIDKmg2JFz0KEFUaWSq1/img.jpg?width=500&amp;amp;height=642&amp;amp;face=0_0_500_642,https://scrap.kakaocdn.net/dn/bqh6X2/hyRQxqbVsE/OWSJln6zhrdOmMkGA4RBvk/img.jpg?width=500&amp;amp;height=642&amp;amp;face=0_0_500_642');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;러닝 타입스크립트&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;자바스크립트 세계를 정복한 타입스크립트는 강력한 타입 안정성에 힘입어 가장 빠르게 성장하고 있다. 언어의 역사를 살펴보며 진화 과정과 작동 방식을 이해하고, 개념 설명을 돕는 수많은&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;www.aladin.co.kr&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Books/Learning TypeScript</category>
      <category>Interface</category>
      <category>Typescript</category>
      <category>러닝타입스크립트</category>
      <category>인터페이스</category>
      <category>타입스크립트</category>
      <author>후끈후끈</author>
      <guid isPermaLink="true">https://likelacoste.tistory.com/65</guid>
      <comments>https://likelacoste.tistory.com/65#entry65comment</comments>
      <pubDate>Sat, 4 Mar 2023 23:09:21 +0900</pubDate>
    </item>
    <item>
      <title>5. 배열</title>
      <link>https://likelacoste.tistory.com/64</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;자바스크립트의&lt;b&gt; 배열은 매우 유연하고 내부에 모든 타입의 값을 혼합해서 저장&lt;/b&gt;할 수 있습니다. 그러나 배열 안에 다른 타입의 값을 혼합해서 사용하거나, 다른 타입의 값을 추가하게 되면 배열을 읽을 때 혼란을 줄 수 있으며, 오류가 발생할 수도 있습니다. 그렇기 때문에 대부분의 배열은 하나의 특정 타입의 값만 가지고 있는 것을 볼 수 있습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;u&gt;&lt;b&gt;타입스크립트는 초기 배열 내부의 값에 대한 타입을 기억하고, 배열이 해당 데이터 타입에서만 작동하도록 제한하여 배열의 데이터 타입을 하나로 유지시킵니다.&lt;/b&gt;&lt;/u&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2023-02-21 10.52.01.png&quot; data-origin-width=&quot;1202&quot; data-origin-height=&quot;262&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/boDI5Z/btr0xPdAV8p/4DmLmouJ98EIN9LoMPQKK1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/boDI5Z/btr0xPdAV8p/4DmLmouJ98EIN9LoMPQKK1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/boDI5Z/btr0xPdAV8p/4DmLmouJ98EIN9LoMPQKK1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FboDI5Z%2Fbtr0xPdAV8p%2F4DmLmouJ98EIN9LoMPQKK1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;666&quot; height=&quot;145&quot; data-filename=&quot;스크린샷 2023-02-21 10.52.01.png&quot; data-origin-width=&quot;1202&quot; data-origin-height=&quot;262&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;위 코드를 보면 타입스크립트가 초기 배열 &lt;code&gt;names&lt;/code&gt;에 담긴 요소를 통해서 배열의 타입을 유추하는 것을 볼 수 있습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;배열 타입&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;배열의 요소 타입 다음에 [ ]을 배치 :&amp;nbsp; &lt;code&gt;let names: string[];&lt;/code&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;Array&amp;lt;타입&amp;gt; : &lt;code&gt;let names: Array&amp;lt;string&amp;gt;;&lt;/code&gt;&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;1️⃣ &lt;b&gt;배열과 함수 타입&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;배열 타입은 함수 타입에 무엇이 있는지 구별하기 위해서 괄호를 사용하여 구문 컨테이너를 만들어야 합니다. (괄호는 에노테이션의 어느 부분이 함수 반환 부분이고 어느 부분이 배열 타입 묶음인지를 나타내는 역할)&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;typescript&quot;&gt;&lt;code&gt;// number 배열을 반환하는 함수
let createNumbers: () =&amp;gt; number[];

// number를 반환하는 함수를 요소로 갖는 배열
let numberCreators: (() =&amp;gt; number)[];&lt;/code&gt;&lt;/pre&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&amp;nbsp;&lt;/h3&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;2️⃣ &lt;b&gt;유니언 타입 배열&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;배열의 각 요소가 &lt;b&gt;여러 타입 중 하나일 수 있음&lt;/b&gt;을 나타내려면 &lt;b&gt;유니언 타입&lt;/b&gt;을 사용해야 합니다. 유니언 타입으로 배열 타입을 사용할 때 에노테이션의 어느 부분이 배열의 콘텐츠이고, 어느 부분이 유니언 타입 묶음인지를 명확하게 나타내야 합니다.(괄호를 사용해서 구분)&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;xquery&quot;&gt;&lt;code&gt;// number 타입 또는 string을 요소로 갖는 배열 타입
let numberOrArrayOfStrings: number | string[];

// number 또는 string을 요소로 갖는 배열 타입
let arrayOfNumberOrStrings: (number | string)[];&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;유니언 타입 배열에서 괄호 사용은 매우 중요한 역할을 합니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;타입스크립트는 배열의 선언에서 &lt;b&gt;두 가지 이상의 요소 타입이 포함되는 경우 &lt;u&gt;유니언 타입의 배열&lt;/u&gt;이라고 유추&lt;/b&gt;합니다. (배열의 요소 타입은 배열에 담긴 요소에 대한 모든 가능한 타입의 집합)&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2023-02-21 11.18.14.png&quot; data-origin-width=&quot;810&quot; data-origin-height=&quot;190&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bgW4YA/btr0r5VRqIG/GXKJyQ8RA16Qe2D9OwaiI0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bgW4YA/btr0r5VRqIG/GXKJyQ8RA16Qe2D9OwaiI0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bgW4YA/btr0r5VRqIG/GXKJyQ8RA16Qe2D9OwaiI0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbgW4YA%2Fbtr0r5VRqIG%2FGXKJyQ8RA16Qe2D9OwaiI0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;666&quot; height=&quot;156&quot; data-filename=&quot;스크린샷 2023-02-21 11.18.14.png&quot; data-origin-width=&quot;810&quot; data-origin-height=&quot;190&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&amp;nbsp;&lt;/h3&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;3️⃣ &lt;b&gt;다차원 배열&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;2차원 배열 또는 배열의 배열은 두 개의 대괄호([ ])를 갖습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2023-02-21 11.27.23.png&quot; data-origin-width=&quot;880&quot; data-origin-height=&quot;432&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/99gp8/btr0yHGePc2/9LNqz2Dj6IJXkLkj0T5HT1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/99gp8/btr0yHGePc2/9LNqz2Dj6IJXkLkj0T5HT1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/99gp8/btr0yHGePc2/9LNqz2Dj6IJXkLkj0T5HT1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F99gp8%2Fbtr0yHGePc2%2F9LNqz2Dj6IJXkLkj0T5HT1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;666&quot; height=&quot;327&quot; data-filename=&quot;스크린샷 2023-02-21 11.27.23.png&quot; data-origin-width=&quot;880&quot; data-origin-height=&quot;432&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;2차원 배열은 배열을 요소로 갖는 배열이라고 볼 수 있기 때문에&amp;nbsp;  아래와 같이 나타낼 수도 있습니다.&lt;/span&gt;&lt;/p&gt;
&lt;pre id=&quot;code_1677155467207&quot; class=&quot;typescript&quot; data-ke-language=&quot;typescript&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;let arrayOfArraysOfNumbers: (number[])[];&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;만약에 타입스크립트가 빈 배열로 선언된 변수를 보게 된다면 어떤 타입으로 유추하게 될까요?&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;타입스크립트는 배열을 &lt;b&gt;&lt;code&gt;any[]&lt;/code&gt;&lt;/b&gt;로 취급하고 모든 타입의 값을 받을 수 있도록 합니다. &lt;b&gt;모든 타입의 값을 받도록 내버려 둔다는 것&lt;/b&gt;은 안전성이 떨어지기 때문에 사용하지 않는 것이 좋습니다.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&amp;nbsp;&lt;/h2&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;배열의 요소&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;타입스크립트는 배열의 요소를 찾아서 해당 배열의 타입을 되돌려줍니다. &lt;b&gt;유니언 타입으로 된 배열의 요소도 그 자체로 동일하게 유니언 타입을 갖습니다.&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2023-02-21 12.50.25.png&quot; data-origin-width=&quot;708&quot; data-origin-height=&quot;504&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/MhrzO/btr0zFOUjkA/k5qoEdfhM730WFKl1XsxD1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/MhrzO/btr0zFOUjkA/k5qoEdfhM730WFKl1XsxD1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/MhrzO/btr0zFOUjkA/k5qoEdfhM730WFKl1XsxD1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FMhrzO%2Fbtr0zFOUjkA%2Fk5qoEdfhM730WFKl1XsxD1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;666&quot; height=&quot;474&quot; data-filename=&quot;스크린샷 2023-02-21 12.50.25.png&quot; data-origin-width=&quot;708&quot; data-origin-height=&quot;504&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;1️⃣ 불안정한 요소&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;타입스크립트의 타입 시스템은 불안정한 부분도 있습니다. 대부분 올바른 타입을 얻을 수 있지만, 때로는 값 타입에 대한 타입 유추가 올바르지 않을 수 있습니다. 특히 배열에서 이러한 모습이 나타납니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;기본적으로 &lt;b&gt;타입스크립트&lt;/b&gt;는 &lt;b&gt;모든 배열의 요소에 대한 접근이 해당 배열의 요소를 반환&lt;/b&gt;한다고 가정하지만, &lt;b&gt;자바스크립트&lt;/b&gt;에서는 &lt;b&gt;배열의 길이보다 큰 인덱스로 배열의 요소에 접근하면 &lt;code&gt;undefined&lt;/code&gt;를 반환&lt;/b&gt;합니다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2023-02-21 13.01.39.png&quot; data-origin-width=&quot;848&quot; data-origin-height=&quot;328&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/SAu7W/btr0xMg0Gsj/zYb8E4folrIqYWRnda2nC1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/SAu7W/btr0xMg0Gsj/zYb8E4folrIqYWRnda2nC1/img.png&quot; data-alt=&quot;타입스크립트는 elements[9000]을 undefined가 아닌 string 타입으로 유추&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/SAu7W/btr0xMg0Gsj/zYb8E4folrIqYWRnda2nC1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FSAu7W%2Fbtr0xMg0Gsj%2FzYb8E4folrIqYWRnda2nC1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;666&quot; height=&quot;258&quot; data-filename=&quot;스크린샷 2023-02-21 13.01.39.png&quot; data-origin-width=&quot;848&quot; data-origin-height=&quot;328&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;타입스크립트는 elements[9000]을 undefined가 아닌 string 타입으로 유추&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;우리는 &lt;code&gt;withString&lt;/code&gt; 함수의 반환 값을 보게 되면 &amp;lsquo;Cannot read property &amp;lsquo;length&amp;rsquo; of undefined' 라는 타입 오류가 발생할 것이라고 생각할 수 있지만, 타입스크립트는 검색된 배열의 요소가 존재하는지 의도적으로 확인하지 않습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;스프레드와 나머지 매개변수&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;나머지 매개변수와 배열 스프레드는 자바스크립트에서 배열과 상호작용하는 핵심 방법입니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;1️⃣ 스프레드&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;자바스크립트에서 &lt;b&gt;&amp;hellip; 스프레드 연산자&lt;/b&gt;를 사용하면 두 배열을 결합할 수 있습니다. 타입스크립트는 결합된 배열의 타입이 무엇인지 유추하는데, 만약 입력된 배열이 동일한 타입이라면 결합된 배열도 동일한 타입이 됩니다. 만약 &lt;b&gt;서로 다른 타입의 두 배열을 결합&lt;/b&gt;하게 되는 경우 &lt;b&gt;두 배열의 타입의 &lt;u&gt;유니언 타입&lt;/u&gt;&lt;/b&gt;이 됩니다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2023-02-21 13.16.44.png&quot; data-origin-width=&quot;1074&quot; data-origin-height=&quot;260&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bN16vV/btr0BD39hbB/mOYedckINJ61kZ8oaBfwM1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bN16vV/btr0BD39hbB/mOYedckINJ61kZ8oaBfwM1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bN16vV/btr0BD39hbB/mOYedckINJ61kZ8oaBfwM1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbN16vV%2Fbtr0BD39hbB%2FmOYedckINJ61kZ8oaBfwM1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;666&quot; height=&quot;161&quot; data-filename=&quot;스크린샷 2023-02-21 13.16.44.png&quot; data-origin-width=&quot;1074&quot; data-origin-height=&quot;260&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&amp;nbsp;&lt;/h3&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;2️⃣ 나머지 매개변수 스프레드&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;나머지 매개변수를 위한 인수로 사용되는 배열은 &lt;b&gt;나머지 매개변수와 동일한 타입&lt;/b&gt;을 가져야 합니다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2023-02-21 13.28.00.png&quot; data-origin-width=&quot;1200&quot; data-origin-height=&quot;580&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/y06TT/btr0uxq52Kw/BhfZuRsLUH3z5ZUNh0E9IK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/y06TT/btr0uxq52Kw/BhfZuRsLUH3z5ZUNh0E9IK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/y06TT/btr0uxq52Kw/BhfZuRsLUH3z5ZUNh0E9IK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fy06TT%2Fbtr0uxq52Kw%2FBhfZuRsLUH3z5ZUNh0E9IK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;666&quot; height=&quot;322&quot; data-filename=&quot;스크린샷 2023-02-21 13.28.00.png&quot; data-origin-width=&quot;1200&quot; data-origin-height=&quot;580&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&amp;nbsp;&lt;/h2&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;튜플&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;자바스크립트 배열은 이론상 어떤 크기라도 될 수 있습니다. 하지만 때로는 &lt;u&gt;&lt;b&gt;튜플(Tuple)&lt;/b&gt;이라고 하는 &lt;b&gt;고정된 크기의 배열&lt;/b&gt;&lt;/u&gt;을 사용하는 것이 유용한 경우가 있습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;튜플 배열은 각 인덱스에 특정 타입을 갖는 요소의 배열&lt;/b&gt;을 말합니다. 튜플 타입을 선언하는 구문은 배열 리터럴처럼 보이지만 요소의 값 대신 타입을 적습니다.&lt;/span&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;튜플 배열은 배열의 모든 가능한 요소를 갖는 유니언 타입보다 더 구체적입니다.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2023-02-21 13.43.37.png&quot; data-origin-width=&quot;1026&quot; data-origin-height=&quot;432&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/sXRFh/btr0BBL1nuH/e6VdkigRUM5JPfOjjMZoQ1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/sXRFh/btr0BBL1nuH/e6VdkigRUM5JPfOjjMZoQ1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/sXRFh/btr0BBL1nuH/e6VdkigRUM5JPfOjjMZoQ1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FsXRFh%2Fbtr0BBL1nuH%2Fe6VdkigRUM5JPfOjjMZoQ1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;666&quot; height=&quot;280&quot; data-filename=&quot;스크린샷 2023-02-21 13.43.37.png&quot; data-origin-width=&quot;1026&quot; data-origin-height=&quot;432&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;자바스크립트에서는 단일 조건을 기반으로 두 개의 변수에 초기값을 설정하는 것처럼 &lt;b&gt;한 번에 여러 값을 할당&lt;/b&gt;하기 위해서는 &lt;b&gt;튜플&lt;/b&gt;과 &lt;b&gt;배열 구조 분해 할당&lt;/b&gt;을 함께 사용합니다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2023-02-21 13.47.39.png&quot; data-origin-width=&quot;728&quot; data-origin-height=&quot;280&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bNgf3n/btr0BAGmrtw/KkSSVD7ce2LQWqebAjiUV0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bNgf3n/btr0BAGmrtw/KkSSVD7ce2LQWqebAjiUV0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bNgf3n/btr0BAGmrtw/KkSSVD7ce2LQWqebAjiUV0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbNgf3n%2Fbtr0BAGmrtw%2FKkSSVD7ce2LQWqebAjiUV0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;666&quot; height=&quot;256&quot; data-filename=&quot;스크린샷 2023-02-21 13.47.39.png&quot; data-origin-width=&quot;728&quot; data-origin-height=&quot;280&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;다음 코드에서 우리는 &lt;code&gt;stringAndNumber&lt;/code&gt; 내부에 &lt;code&gt;[string, number]&lt;/code&gt;가 있는 것을 볼 수 있지만, 타입스크립트는 튜플 타입보다는 더 일반적인 &lt;code&gt;(string | number)[]&lt;/code&gt; 타입으로 유추합니다.&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;angelscript&quot;&gt;&lt;code&gt;const stringAndNumber = ['string', 123];
// stringAndNumber: (string | number)[]

const pairTupleLoose: [string, number] = stringAndNumber; // 오류
// Type '(string | number)[]' is not assignable to type '[string, number]'.
// Target requires 2 element(s) but source may have fewer.&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;만약 &lt;code&gt;stringAndNumber&lt;/code&gt; 가 &lt;code&gt;[string, number]&lt;/code&gt; 자체로 선언되었다면, &lt;code&gt;pairTupleLoose&lt;/code&gt;에 대한 값이 할당 되어 오류가 발생하지 않았을 것입니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;그리고 타입스크립트는 튜플 타입의 튜플이 얼마나 많은 요소가 있는지 알고 있기 때문에 &lt;b&gt;배열의 길이가 다른 튜플은 서로 할당할 수 없습니다.&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2023-02-21 16.24.37.png&quot; data-origin-width=&quot;1236&quot; data-origin-height=&quot;322&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bV6BnE/btr0sAIuDyO/aIr7uS4rAcTG8ZkdymSQzK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bV6BnE/btr0sAIuDyO/aIr7uS4rAcTG8ZkdymSQzK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bV6BnE/btr0sAIuDyO/aIr7uS4rAcTG8ZkdymSQzK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbV6BnE%2Fbtr0sAIuDyO%2FaIr7uS4rAcTG8ZkdymSQzK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;666&quot; height=&quot;174&quot; data-filename=&quot;스크린샷 2023-02-21 16.24.37.png&quot; data-origin-width=&quot;1236&quot; data-origin-height=&quot;322&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;1️⃣ 나머지 매개변수로서의 튜플&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;튜플은 구체적인 길이와 요소 타입 정보를 가지는 배열임을 알 수 있었습니다. 이러한 튜플의 특징은 &lt;b&gt;함수에 전달할 인수를 저장하는데 유용&lt;/b&gt;합니다. 타입스크립트는 &lt;code&gt;...&lt;/code&gt; 나머지 매개변수로 전달된 튜플에 정확한 타입 검사를 제공할 수 있습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;아래의 코드에서 &lt;code&gt;stringAndNumberPair&lt;/code&gt; 함수의 매개변수는 &lt;code&gt;string&lt;/code&gt;과 &lt;code&gt;number&lt;/code&gt; 타입 입니다. 하지만 함수의 매개변수로 &lt;code&gt;(string | number)[]&lt;/code&gt; 타입의 값을 인수로 전달하려고 하면 둘 다 동일한 타입이거나 타입의 잘못된 순서로 인해 내용이 일치하지 않을 가능성이 있습니다.(타입의 안정성을 보장할 수 없음)&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;code&gt;pairTupleCorrect&lt;/code&gt;와 같이 값이 &lt;code&gt;[string, number]&lt;/code&gt; 튜플이라고 선언한다면, 타입스크립트가 값이 일치한다는 것을 유추할 수 있어 타입 오류가 발생하지 않습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2023-02-21 16.37.32.png&quot; data-origin-width=&quot;1260&quot; data-origin-height=&quot;732&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ct584K/btr0zTfieVq/MQNjuY1GNOKPWwYeaR4D7K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ct584K/btr0zTfieVq/MQNjuY1GNOKPWwYeaR4D7K/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ct584K/btr0zTfieVq/MQNjuY1GNOKPWwYeaR4D7K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fct584K%2Fbtr0zTfieVq%2FMQNjuY1GNOKPWwYeaR4D7K%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;666&quot; height=&quot;387&quot; data-filename=&quot;스크린샷 2023-02-21 16.37.32.png&quot; data-origin-width=&quot;1260&quot; data-origin-height=&quot;732&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;나머지 매개변수 튜플을 사용하고 싶다면 여러 번 함수를 호출하는 인수 목록을 배열에 저장해 함께 사용할 수 있습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2023-02-21 16.51.56.png&quot; data-origin-width=&quot;894&quot; data-origin-height=&quot;474&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/oOC48/btr0yiGFP4o/w91HvI4yr5A0YlB3H3dpqk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/oOC48/btr0yiGFP4o/w91HvI4yr5A0YlB3H3dpqk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/oOC48/btr0yiGFP4o/w91HvI4yr5A0YlB3H3dpqk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FoOC48%2Fbtr0yiGFP4o%2Fw91HvI4yr5A0YlB3H3dpqk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;666&quot; height=&quot;353&quot; data-filename=&quot;스크린샷 2023-02-21 16.51.56.png&quot; data-origin-width=&quot;894&quot; data-origin-height=&quot;474&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&amp;nbsp;&lt;/h3&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;2️⃣ &lt;b&gt;튜플 추론&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;타입스크립트는 생성되는 배열에 대한 타입을 튜플 타입이 아닌 길이가 정해져 있지 않은 배열(가변 길이의 배열)로 취급하여 유니언 타입 배열로 유추합니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&amp;rarr; 배열이 변수의 초기값 또는 함수에 대한 반환값으로 사용되는 경우, 고정된 크기의 튜플이 아니라 유연한 크기의 배열로 가정&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2023-02-23 21.56.04.png&quot; data-origin-width=&quot;868&quot; data-origin-height=&quot;466&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/nlBve/btr0w00TJwN/Zag4UbDLzUatg1MpEFdnOK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/nlBve/btr0w00TJwN/Zag4UbDLzUatg1MpEFdnOK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/nlBve/btr0w00TJwN/Zag4UbDLzUatg1MpEFdnOK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FnlBve%2Fbtr0w00TJwN%2FZag4UbDLzUatg1MpEFdnOK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;666&quot; height=&quot;358&quot; data-filename=&quot;스크린샷 2023-02-23 21.56.04.png&quot; data-origin-width=&quot;868&quot; data-origin-height=&quot;466&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;code&gt;stringAndSize&lt;/code&gt; 함수의 반환값의 타입은 &lt;code&gt;[string, number]&lt;/code&gt;가 아니라 &lt;code&gt;(string | number)[]&lt;/code&gt;를 반환하는 것을 볼 수 있습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;3️⃣ &lt;b&gt;명시적 튜플 타입&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;함수에 대한 반환 타입 에노테이션처럼 튜플 타입도 타입 에노테이션에 사용할 수 있습니다. 함수가 튜플 타입을 반환한다고 선언되고, 배열 리터럴을 반환한다면 해당 배열 리터럴은 일반적인 가변 길이의 배열 대신 튜플로 간주됩니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2023-02-21 17.22.53.png&quot; data-origin-width=&quot;898&quot; data-origin-height=&quot;350&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bcjwfW/btr0ybgxmTO/9EQIkfvZakEMFa6dyCczTk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bcjwfW/btr0ybgxmTO/9EQIkfvZakEMFa6dyCczTk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bcjwfW/btr0ybgxmTO/9EQIkfvZakEMFa6dyCczTk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbcjwfW%2Fbtr0ybgxmTO%2F9EQIkfvZakEMFa6dyCczTk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;666&quot; height=&quot;260&quot; data-filename=&quot;스크린샷 2023-02-21 17.22.53.png&quot; data-origin-width=&quot;898&quot; data-origin-height=&quot;350&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;code&gt;stringAndSize&lt;/code&gt; 함수는 &lt;code&gt;string&lt;/code&gt;과 &lt;code&gt;number&lt;/code&gt;인 튜플을 반환한다고 명백하게 명시되어 있습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;4️⃣ &lt;b&gt;const 어서션&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;명시적 타입 에노테이션에 튜플 타입을 입력하는 작업은 &lt;b&gt;코드 변경에 따라 계속해서 작성 및 수정이 필요한 구문을 추가&lt;/b&gt;해야한다는 단점을 가지고 있습니다. 이때 const 어서션을 사용합니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;const 어서션인 &lt;u&gt;&lt;b&gt;as const &lt;/b&gt;&lt;/u&gt;연산자는 값 뒤에 넣어서 사용&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class=&quot;actionscript&quot;&gt;&lt;code&gt;const unionArray = [123, 'Kim'];
// unionArray: (string | number)[]

const readonlyTuple = [123, 'Kim'] as const;
// readonlyTuple: readonly [123, &quot;Kim&quot;]&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;const 어서션은 유연한 크기의 배열을 고정된 크기의 &lt;b&gt;튜플로 전환&lt;/b&gt;하는 것을 넘어서, 해당 튜플이 &lt;u&gt;&lt;b&gt;읽기 전용(read-only)이고 값이 수정 될 수 없음&lt;/b&gt;&lt;/u&gt;을 나타냅니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2023-02-21 19.12.04.png&quot; data-origin-width=&quot;996&quot; data-origin-height=&quot;432&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ccRfsG/btr0yI6bp73/Sj09hHlsZAG23wn6mt3dAk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ccRfsG/btr0yI6bp73/Sj09hHlsZAG23wn6mt3dAk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ccRfsG/btr0yI6bp73/Sj09hHlsZAG23wn6mt3dAk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FccRfsG%2Fbtr0yI6bp73%2FSj09hHlsZAG23wn6mt3dAk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;666&quot; height=&quot;289&quot; data-filename=&quot;스크린샷 2023-02-21 19.12.04.png&quot; data-origin-width=&quot;996&quot; data-origin-height=&quot;432&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;code&gt;unionArray&lt;/code&gt;는 전형적인 명시적 튜플 타입이므로 값을 수정할 수 있습니다. 하지만 &lt;code&gt;as const&lt;/code&gt;는 값이 변경될 수 있는 &lt;code&gt;readonlyTuple&lt;/code&gt;에 할당할 수 없도록 하고, 상수 &lt;code&gt;pairConst&lt;/code&gt;의 요소의 값을 수정을 허용하지 않습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;실제로 &lt;b&gt;읽기 전용 튜플은 함수 반환에 편리&lt;/b&gt;합니다. 튜플을 반환하는 함수로부터 반환된 값은 보통 즉시 구조화되지 않으므로 읽기 전용인 튜플은 함수를 사용하는데 방해가 되지 않습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2023-02-21 19.19.39.png&quot; data-origin-width=&quot;1032&quot; data-origin-height=&quot;348&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/wnCSE/btr0uwTg4yj/4dkGdidUwNv8DkzA35tVc1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/wnCSE/btr0uwTg4yj/4dkGdidUwNv8DkzA35tVc1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/wnCSE/btr0uwTg4yj/4dkGdidUwNv8DkzA35tVc1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FwnCSE%2Fbtr0uwTg4yj%2F4dkGdidUwNv8DkzA35tVc1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;666&quot; height=&quot;225&quot; data-filename=&quot;스크린샷 2023-02-21 19.19.39.png&quot; data-origin-width=&quot;1032&quot; data-origin-height=&quot;348&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.aladin.co.kr/shop/wproduct.aspx?ItemId=307683870&quot;&gt;https://www.aladin.co.kr/shop/wproduct.aspx?ItemId=307683870&lt;/a&gt;&lt;span style=&quot;background-color: #ffffff; color: #000000;&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1677157347693&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;books.book&quot; data-og-title=&quot;러닝 타입스크립트&quot; data-og-description=&quot;자바스크립트 세계를 정복한 타입스크립트는 강력한 타입 안정성에 힘입어 가장 빠르게 성장하고 있다. 언어의 역사를 살펴보며 진화 과정과 작동 방식을 이해하고, 개념 설명을 돕는 수많은 &quot; data-og-host=&quot;www.aladin.co.kr&quot; data-og-source-url=&quot;https://www.aladin.co.kr/shop/wproduct.aspx?ItemId=307683870&quot; data-og-url=&quot;https://www.aladin.co.kr/shop/wproduct.aspx?ItemId=307683870&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/vkJEu/hyRJTAlYqm/gDQoLXoxrU6Rs9pmBxXnGK/img.jpg?width=500&amp;amp;height=642&amp;amp;face=0_0_500_642,https://scrap.kakaocdn.net/dn/ya4C4/hyRImjRIel/ssNOobha6CpPHrwGOhtAk1/img.jpg?width=500&amp;amp;height=642&amp;amp;face=0_0_500_642&quot;&gt;&lt;a href=&quot;https://www.aladin.co.kr/shop/wproduct.aspx?ItemId=307683870&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://www.aladin.co.kr/shop/wproduct.aspx?ItemId=307683870&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/vkJEu/hyRJTAlYqm/gDQoLXoxrU6Rs9pmBxXnGK/img.jpg?width=500&amp;amp;height=642&amp;amp;face=0_0_500_642,https://scrap.kakaocdn.net/dn/ya4C4/hyRImjRIel/ssNOobha6CpPHrwGOhtAk1/img.jpg?width=500&amp;amp;height=642&amp;amp;face=0_0_500_642');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;러닝 타입스크립트&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;자바스크립트 세계를 정복한 타입스크립트는 강력한 타입 안정성에 힘입어 가장 빠르게 성장하고 있다. 언어의 역사를 살펴보며 진화 과정과 작동 방식을 이해하고, 개념 설명을 돕는 수많은&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;www.aladin.co.kr&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Books/Learning TypeScript</category>
      <category>as const</category>
      <category>Typescript</category>
      <category>러닝타입스크립트</category>
      <category>배열타입</category>
      <category>타입스크립트</category>
      <category>튜플타입</category>
      <author>후끈후끈</author>
      <guid isPermaLink="true">https://likelacoste.tistory.com/64</guid>
      <comments>https://likelacoste.tistory.com/64#entry64comment</comments>
      <pubDate>Thu, 23 Feb 2023 22:03:00 +0900</pubDate>
    </item>
    <item>
      <title>4. 함수</title>
      <link>https://likelacoste.tistory.com/63</link>
      <description>&lt;blockquote data-ke-style=&quot;style1&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;한쪽 끝에는 함수 인수가 있고, 다른 쪽 끝에는 반환 타입이 있다.&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;/blockquote&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;함수의 매개변수&lt;/span&gt;&lt;/b&gt;&lt;/h2&gt;
&lt;pre class=&quot;javascript&quot;&gt;&lt;code&gt;const eating = (food) =&amp;gt; {
        console.log(`Give me the ${food}!`)
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;code&gt;eating&lt;/code&gt; 함수를 작성한 개발자가 매개변수 &lt;code&gt;food&lt;/code&gt;를 제공하기 위해 의도한 값의 타입은 무엇일까요? &lt;/span&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;code&gt;string&lt;/code&gt;일까요? 아니면 재정의된 &lt;code&gt;toString()&lt;/code&gt; 메서드가 있는 객체일까요? 매개변수의 타입에 대해 과연 누가 알 수 있을까요?&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;명시적으로 타입 정보가 선언되지 않고는 매개변수의 타입에 대해 알 수 없습니다. 타입스크립트는 이와 같은 매개변수를 보면 &lt;code&gt;any&lt;/code&gt;타입으로 간주하여 매개변수의 타입은 무엇이든 될 수 있습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;변수와 마찬가지로 타입스크립트를 사용하면 타입 에노테이션으로 함수 매개변수의 타입을 선언할 수 있습니다.&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;typescript&quot;&gt;&lt;code&gt;const eating = (food: string) =&amp;gt; {
        console.log(`Give me the ${food}!`)
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;이렇게 타입의 정보를 명시적으로 선언하게 되니 &lt;code&gt;food&lt;/code&gt;의 타입이 무엇인지 알 수 있습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;필수 매개변수&lt;/span&gt;&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;자바스크립트는 인수의 수와 상관없이 함수를 호출할 수 있습니다. 하지만 타입스크립트는 &lt;b&gt;함수에 선언된 모든 매개변수가 필수&lt;/b&gt;라고 가정합니다. 때문에 함수가 잘못된 수의 인수로 호출되면, 타입스크립트는 타입 오류를 발생합니다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2023-02-18 15.13.55.png&quot; data-origin-width=&quot;828&quot; data-origin-height=&quot;494&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/crlyit/btrZ7rjFapL/rFGadLxEGQOMdmIEWqM9ZK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/crlyit/btrZ7rjFapL/rFGadLxEGQOMdmIEWqM9ZK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/crlyit/btrZ7rjFapL/rFGadLxEGQOMdmIEWqM9ZK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fcrlyit%2FbtrZ7rjFapL%2FrFGadLxEGQOMdmIEWqM9ZK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;666&quot; height=&quot;397&quot; data-filename=&quot;스크린샷 2023-02-18 15.13.55.png&quot; data-origin-width=&quot;828&quot; data-origin-height=&quot;494&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;함수에 필수 매개변수(required parameter)를 제공하도록 지정하면 예상되는 모든 인수값을 함수 안에 존재하도록 만들어 &lt;b&gt;타입 안전성을 강화&lt;/b&gt;하는데 도움이 됩니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;선택적 매개변수&lt;/span&gt;&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;자바스크립트에서 함수 매개변수가 제공되지 않으면 함수 내부의 인수값은 &lt;code&gt;undefined&lt;/code&gt; 로 기본값이 설정됩니다. 타입스크립트는 매개변수가 제공되지 않으면 타입 오류를 발생하게 됩니다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2023-02-18 15.30.01.png&quot; data-origin-width=&quot;874&quot; data-origin-height=&quot;372&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/yZ95A/btrZ78RHx3T/AUGAU6QJ2EHKuzRKzXT4IK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/yZ95A/btrZ78RHx3T/AUGAU6QJ2EHKuzRKzXT4IK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/yZ95A/btrZ78RHx3T/AUGAU6QJ2EHKuzRKzXT4IK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FyZ95A%2FbtrZ78RHx3T%2FAUGAU6QJ2EHKuzRKzXT4IK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;666&quot; height=&quot;283&quot; data-filename=&quot;스크린샷 2023-02-18 15.30.01.png&quot; data-origin-width=&quot;874&quot; data-origin-height=&quot;372&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;때로는 함수 매개변수를 제공할 필요가 없을 때나, undefined 값을 위해 의도적으로 사용하는 경우, 우리는 타입스크립트가 타입오류를 보고하지 않았으면 합니다. 이때 사용할 수 있는 것이 &lt;b&gt;선택적 매개변수&lt;/b&gt; 입니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;선택적 객체 타입 속성과 유사하게 타입 에노테이션의 &lt;code&gt;:&lt;/code&gt; 앞에 &lt;code&gt;?&lt;/code&gt;를 추가해서 작성하면 매개변수가 &lt;b&gt;선택적&lt;/b&gt;이라고 표시합니다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2023-02-18 15.34.01.png&quot; data-origin-width=&quot;928&quot; data-origin-height=&quot;504&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/beVevs/btrZ9FuJDWm/lgd1fcbWzo5K3kvkEakDP1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/beVevs/btrZ9FuJDWm/lgd1fcbWzo5K3kvkEakDP1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/beVevs/btrZ9FuJDWm/lgd1fcbWzo5K3kvkEakDP1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbeVevs%2FbtrZ9FuJDWm%2Flgd1fcbWzo5K3kvkEakDP1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;666&quot; height=&quot;362&quot; data-filename=&quot;스크린샷 2023-02-18 15.34.01.png&quot; data-origin-width=&quot;928&quot; data-origin-height=&quot;504&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;위 코드에서 매개변수 &lt;code&gt;second&lt;/code&gt; 는 항상 암묵적으로 &lt;code&gt;undefined&lt;/code&gt;가 될 수 있기 때문에 &lt;code&gt;string | undefined&lt;/code&gt; 타입이 되며, &lt;code&gt;if&lt;/code&gt; 문에 따라 &lt;code&gt;string&lt;/code&gt; 타입으로 좁혀집니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;여기서 주의해야하는 것은 &lt;b&gt;&lt;span style=&quot;color: #ffc1c8;&quot;&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;선택적 매개변수는&lt;/span&gt; &lt;code&gt;| undefined&lt;/code&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;를 포함하는 유니언 타입 매개변수와는 다르다는 점&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;입니다. 선택적 매개변수가 아닌&lt;b&gt; 매개변수&lt;/b&gt;는 값이 명시적으로 &lt;code&gt;undefined&lt;/code&gt;일지라도 &lt;b&gt;항상 제공&lt;/b&gt;되어야 하지만, &lt;b&gt;선택적 매개변수&lt;/b&gt;는 &lt;b&gt;값이 제공되지 않아&lt;/b&gt;도 타입 오류가 발생하지 않습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;함수에서 사용되는 &lt;u&gt;모든 선택적 매개변수는 &lt;b&gt;마지막 매개변수&lt;/b&gt;&lt;/u&gt;여야 합니다. 필수 매개변수 이전에 선택적 매개변수를 위치시키면 타입스크립트 구문 오류가 발생합니다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2023-02-18 19.48.32.png&quot; data-origin-width=&quot;1026&quot; data-origin-height=&quot;128&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dDGcLK/btrZ7p0tUlg/pKKNXl8IXQaDIKsfjjtNBK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dDGcLK/btrZ7p0tUlg/pKKNXl8IXQaDIKsfjjtNBK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dDGcLK/btrZ7p0tUlg/pKKNXl8IXQaDIKsfjjtNBK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdDGcLK%2FbtrZ7p0tUlg%2FpKKNXl8IXQaDIKsfjjtNBK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;666&quot; height=&quot;83&quot; data-filename=&quot;스크린샷 2023-02-18 19.48.32.png&quot; data-origin-width=&quot;1026&quot; data-origin-height=&quot;128&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&amp;nbsp;&lt;/h4&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;기본 매개변수&lt;/span&gt;&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;선택적 매개변수를 선언할 때 &lt;code&gt;=&lt;/code&gt;를 사용하여 &lt;b&gt;기본값을 제공하여 선언&lt;/b&gt;할 수 있습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2023-02-18 20.03.29.png&quot; data-origin-width=&quot;960&quot; data-origin-height=&quot;392&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/vUW4T/btrZ9GUGXkl/WAqJzIBIRv8tBuQvHOF5Mk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/vUW4T/btrZ9GUGXkl/WAqJzIBIRv8tBuQvHOF5Mk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/vUW4T/btrZ9GUGXkl/WAqJzIBIRv8tBuQvHOF5Mk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FvUW4T%2FbtrZ9GUGXkl%2FWAqJzIBIRv8tBuQvHOF5Mk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;666&quot; height=&quot;272&quot; data-filename=&quot;스크린샷 2023-02-18 20.03.29.png&quot; data-origin-width=&quot;960&quot; data-origin-height=&quot;392&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;code&gt;eating&lt;/code&gt;함수의 매개변수 중 하나인 &lt;code&gt;count&lt;/code&gt;는 0이라는 값을 기본값으로 선언한 것을 볼 수 있습니다.&lt;b&gt;&lt;code&gt;?&lt;/code&gt;를 사용하지 않았지만 타입스크립트는 해당 매개변수를 선택&lt;/b&gt; 매개변수로&lt;b&gt; 유추&lt;/b&gt;합니다. 그리고 암묵적으로 함수 내부에 &lt;code&gt;| undefined&lt;/code&gt; 유니언 타입이 추가되어, 함수의 매개변수에 대해 인수를 누락하거나 &lt;code&gt;undefined&lt;/code&gt; 인수를 사용해서 호출하는 것을 허용합니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;그리고 매개변수에 기본값이 있고 타입 애노테이션이 없는 경우, 타입스크립트는 해당 &lt;b&gt;기본값을 기반으로 매개변수 타입을 유추&lt;/b&gt;합니다. (&lt;code&gt;count&lt;/code&gt;를 &lt;code&gt;number&lt;/code&gt; 타입으로 유추하지만 함수를 호출하는 코드에서는 &lt;b&gt;선택적&lt;/b&gt; &lt;code&gt;&lt;b&gt;number | undefined&lt;/b&gt;&lt;/code&gt;가 됩니다. )&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;나머지 매개변수&lt;/span&gt;&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;u&gt;&lt;code&gt;&lt;b&gt;...&lt;/b&gt; 스프레드 연산자&lt;/code&gt;는 함수 선언의 &lt;b&gt;마지막 매개변수&lt;/b&gt;&lt;/u&gt;에 위치하여, 해당 매개변수에서 시작해 함수에 전달된 &lt;b&gt;나머지(rest) 인수&lt;/b&gt;가 모두 단일 &lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;배열에 저장&lt;/b&gt;&lt;/span&gt;됩니다. 타입스크립트는 이러한 나머지 매개변수(rest parameter)의 타입을 일반 매개변수와 유사하게 선언할 수 있습니다.(인수 배열을 나타내기 위해서 끝에 &lt;b&gt;&lt;span style=&quot;color: #006dd7;&quot;&gt;[ ]구문이 추가&lt;/span&gt;&lt;/b&gt;되어야 한다.)&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2023-02-19 22.59.16.png&quot; data-origin-width=&quot;1182&quot; data-origin-height=&quot;522&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/kPri0/btrZ66mxaiA/ZpNnbdzgMyCqpMqSFrk7OK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/kPri0/btrZ66mxaiA/ZpNnbdzgMyCqpMqSFrk7OK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/kPri0/btrZ66mxaiA/ZpNnbdzgMyCqpMqSFrk7OK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FkPri0%2FbtrZ66mxaiA%2FZpNnbdzgMyCqpMqSFrk7OK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;666&quot; height=&quot;294&quot; data-filename=&quot;스크린샷 2023-02-19 22.59.16.png&quot; data-origin-width=&quot;1182&quot; data-origin-height=&quot;522&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&amp;nbsp;&lt;/h4&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;반환 타입&lt;/span&gt;&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;타입스크립트는 지각적(perceptive)이여서, &lt;b&gt;함수가 반환할 수 있는 가능한 모든 값을 알면 함수가 반환하는 타입을 유추&lt;/b&gt; 할 수 있습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2023-02-19 23.04.53.png&quot; data-origin-width=&quot;1142&quot; data-origin-height=&quot;604&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/YiiQY/btrZ7rxdRso/vZUlQ3ol6fV21ccB1Pht7k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/YiiQY/btrZ7rxdRso/vZUlQ3ol6fV21ccB1Pht7k/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/YiiQY/btrZ7rxdRso/vZUlQ3ol6fV21ccB1Pht7k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FYiiQY%2FbtrZ7rxdRso%2FvZUlQ3ol6fV21ccB1Pht7k%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;666&quot; height=&quot;352&quot; data-filename=&quot;스크린샷 2023-02-19 23.04.53.png&quot; data-origin-width=&quot;1142&quot; data-origin-height=&quot;604&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;만약에 함수에 다른 값을 가진 여러 개의 반환문을 포함하고 있다면, 타입스크립트는 반환 타입(return type)을 가능한 모든 반환 타입의 조합으로 유추하게 됩니다. (&lt;code&gt;getBookAt&lt;/code&gt; 함수의 반환 타입을 &lt;code&gt;string | undefined&lt;/code&gt;로 유추함)&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;변수와 마찬가지로 타입 에노테이션을 사용하여 함수의 반환 타입을 명시적으로 선언할 수 있지만, 선언하지 않는 것이 좋습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;반환 타입의 위치(명시적으로 선언)&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;함수 선언의 경우 &lt;code&gt;{&lt;/code&gt; 앞에 배치&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;화살표함수의 경우&lt;code&gt;=&amp;gt;&lt;/code&gt; 앞에 배치&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2023-02-19 23.21.50.png&quot; data-origin-width=&quot;1172&quot; data-origin-height=&quot;444&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bokHVf/btrZ6i8CG7r/jxRsBkOkucWxh1oRXJMYoK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bokHVf/btrZ6i8CG7r/jxRsBkOkucWxh1oRXJMYoK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bokHVf/btrZ6i8CG7r/jxRsBkOkucWxh1oRXJMYoK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbokHVf%2FbtrZ6i8CG7r%2FjxRsBkOkucWxh1oRXJMYoK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;666&quot; height=&quot;252&quot; data-filename=&quot;스크린샷 2023-02-19 23.21.50.png&quot; data-origin-width=&quot;1172&quot; data-origin-height=&quot;444&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&amp;nbsp;&lt;/h4&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;함수 타입&lt;/span&gt;&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;자바스크립트에서는 함수를 값으로 전달 할 수 있습니다. 즉, 함수를 가지기 위한 매개변수 또는 변수의 타입을 선언하는 방법이 필요합니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;함수 타입&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;함수 타입 구문은 화살표 함수와 유사하지만 함수 본문 대신 타입이 있습니다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;code&gt;( ) =&amp;gt; string&lt;/code&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;함수 타입은 콜백 매개변수(함수로 호출되는 매개변수)를 설명하는데 자주 사용됩니다.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2023-02-19 23.39.04.png&quot; data-origin-width=&quot;996&quot; data-origin-height=&quot;904&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/zwCXw/btrZ7p0t5AO/j06T86OivGjfH1ECuMTR1K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/zwCXw/btrZ7p0t5AO/j06T86OivGjfH1ECuMTR1K/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/zwCXw/btrZ7p0t5AO/j06T86OivGjfH1ECuMTR1K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FzwCXw%2FbtrZ7p0t5AO%2Fj06T86OivGjfH1ECuMTR1K%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;666&quot; height=&quot;604&quot; data-filename=&quot;스크린샷 2023-02-19 23.39.04.png&quot; data-origin-width=&quot;996&quot; data-origin-height=&quot;904&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;함수 타입은 다른 타입이 사용되는 모든 곳에 배치할 수 있습니다.(유니언 타입도 가능)&lt;/span&gt;&lt;/p&gt;
&lt;ol style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;code&gt;let returnString: () =&amp;gt; string&lt;/code&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;code&gt;let returnStringOrUndefined: () =&amp;gt; string | undefined&lt;/code&gt;&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;code&gt;let maybeReturnString: (() =&amp;gt; string) | undefined&lt;/code&gt;&lt;/span&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;2번과 3번에서의 타입 선언은 비슷해 보이지만 완전히 다른 타입입니다. 2번의 타입은 &lt;b&gt;string | undefined 유니언을 반환하는 함수&lt;/b&gt; 이지만, 3번의 타입은 &lt;b&gt;undefined 나 string을 반환하는 함수&lt;/b&gt; 입니다. 유니언 타입의 에노테이션에서 함수 반환 위치를 나타내거나 유니언 타입을 감싸는 부분을 표시할 때 괄호를 사용합니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #f6e199;&quot;&gt;&lt;b&gt;❓ 매개변수로 사용되는 인라인 함수(inline function)를 포함하여 작성한 모든 함수에 대해 매개변수의 타입을 선언해야 할까요?&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;그렇지 않습니다. 타입스크립트는 선언된 타입의 위치에 제공된 함수의 매개변수 타입을 유추할 수 있기 때문에 따로 선언하지 않아도 타입 오류가 발생하지 않습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2023-02-19 23.58.29.png&quot; data-origin-width=&quot;646&quot; data-origin-height=&quot;280&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cFKVOW/btrZ700p6ua/QkyacckaiTNRQsttaKNxOk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cFKVOW/btrZ700p6ua/QkyacckaiTNRQsttaKNxOk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cFKVOW/btrZ700p6ua/QkyacckaiTNRQsttaKNxOk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcFKVOW%2FbtrZ700p6ua%2FQkyacckaiTNRQsttaKNxOk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;666&quot; height=&quot;289&quot; data-filename=&quot;스크린샷 2023-02-19 23.58.29.png&quot; data-origin-width=&quot;646&quot; data-origin-height=&quot;280&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;또한 타입스크립트는 함수를 매개변수로 갖는 함수에 인수로 전달된 함수는 해당 매개변수 타입도 유추할 수 있습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2023-02-20 00.05.23.png&quot; data-origin-width=&quot;934&quot; data-origin-height=&quot;354&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/zjstB/btrZ7bnS2Ev/TlUk9yTlSKLrKdxaOpCK4k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/zjstB/btrZ7bnS2Ev/TlUk9yTlSKLrKdxaOpCK4k/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/zjstB/btrZ7bnS2Ev/TlUk9yTlSKLrKdxaOpCK4k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FzjstB%2FbtrZ7bnS2Ev%2FTlUk9yTlSKLrKdxaOpCK4k%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;666&quot; height=&quot;252&quot; data-filename=&quot;스크린샷 2023-02-20 00.05.23.png&quot; data-origin-width=&quot;934&quot; data-origin-height=&quot;354&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&amp;nbsp;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;그 외 반환 타입&lt;/span&gt;&lt;/b&gt;&lt;/h2&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;void 반환 타입&lt;/span&gt;&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;함수 중에는 값을 반환하는 함수도 있고 어떠한 값도 반환하지 않는 함수도 있습니다. (&lt;code&gt;return&lt;/code&gt; 문이 없는 함수이거나 값을 반환하지 않는 &lt;code&gt;return&lt;/code&gt; 문을 갖은 함수) 타입스크립트는 &lt;code&gt;void&lt;/code&gt; 키워드를 사용하여 반환 값이 없는 함수의 반환 타입을 확인할 수 있습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2023-02-20 00.18.44.png&quot; data-origin-width=&quot;872&quot; data-origin-height=&quot;396&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dIxNct/btrZ6I7oorf/GjcGUCCG8HkUcJHa7UBHF0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dIxNct/btrZ6I7oorf/GjcGUCCG8HkUcJHa7UBHF0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dIxNct/btrZ6I7oorf/GjcGUCCG8HkUcJHa7UBHF0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdIxNct%2FbtrZ6I7oorf%2FGjcGUCCG8HkUcJHa7UBHF0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;666&quot; height=&quot;302&quot; data-filename=&quot;스크린샷 2023-02-20 00.18.44.png&quot; data-origin-width=&quot;872&quot; data-origin-height=&quot;396&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;자바스크립트 함수는 실제값이 반환되지 않으면 기본으로 모두 &lt;code&gt;undefined&lt;/code&gt;를 반환하지만, &lt;code&gt;void&lt;/code&gt;는 &lt;code&gt;undefined&lt;/code&gt;와 동일하지 않습니다. &lt;b&gt;&lt;code&gt;void&lt;/code&gt;는 함수의 반환 타입을 무시된다는 것을 의미&lt;/b&gt;하고, &lt;b&gt;&lt;code&gt;undefined&lt;/code&gt;는 반환되는 리터럴 값&lt;/b&gt;입니다. &lt;code&gt;undefined&lt;/code&gt;를 포함하고 있지만 &lt;code&gt;void&lt;/code&gt; 타입의 값을 할당하려고 하면 타입 오류가 발생합니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #f6e199;&quot;&gt;&lt;b&gt;❗️ void 타입은 함수의 반환값이 아니라 함수에서 반한되는 모든 값을 무시하는 타입스크립트의 키워드입니다.&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&amp;nbsp;&lt;/h3&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;never 반환 타입&lt;/span&gt;&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;code&gt;never&lt;/code&gt; 반환 함수는 &lt;b&gt;(의도적으로) 항상 오류를 발생시키거나 무한 루프를 실행하는 함수&lt;/b&gt;입니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;함수가 절대 반환하지 않도록 의도하려면 명시적 : &lt;code&gt;never&lt;/code&gt; 타입 에노테이션을 추가해 해당 함수를 호출한 후 모든 코드가 실행되지 않음을 나타냅니다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2023-02-20 00.37.50.png&quot; data-origin-width=&quot;1038&quot; data-origin-height=&quot;414&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/yMY0D/btrZ6IzuCLs/yHcbi6H8tD71jjhGK1egsK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/yMY0D/btrZ6IzuCLs/yHcbi6H8tD71jjhGK1egsK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/yMY0D/btrZ6IzuCLs/yHcbi6H8tD71jjhGK1egsK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FyMY0D%2FbtrZ6IzuCLs%2FyHcbi6H8tD71jjhGK1egsK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;666&quot; height=&quot;266&quot; data-filename=&quot;스크린샷 2023-02-20 00.37.50.png&quot; data-origin-width=&quot;1038&quot; data-origin-height=&quot;414&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #f6e199;&quot;&gt;&lt;b&gt;❗️ void는 아무것도 반환하지 않는 함수를 위한 것이고, never은 절대 반환하지 않는 함수를 위한 것입니다.&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.aladin.co.kr/shop/wproduct.aspx?ItemId=307683870&quot;&gt;https://www.aladin.co.kr/shop/wproduct.aspx?ItemId=307683870&lt;/a&gt;&lt;span style=&quot;background-color: #ffffff; color: #000000;&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1677157401890&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;books.book&quot; data-og-title=&quot;러닝 타입스크립트&quot; data-og-description=&quot;자바스크립트 세계를 정복한 타입스크립트는 강력한 타입 안정성에 힘입어 가장 빠르게 성장하고 있다. 언어의 역사를 살펴보며 진화 과정과 작동 방식을 이해하고, 개념 설명을 돕는 수많은 &quot; data-og-host=&quot;www.aladin.co.kr&quot; data-og-source-url=&quot;https://www.aladin.co.kr/shop/wproduct.aspx?ItemId=307683870&quot; data-og-url=&quot;https://www.aladin.co.kr/shop/wproduct.aspx?ItemId=307683870&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/vkJEu/hyRJTAlYqm/gDQoLXoxrU6Rs9pmBxXnGK/img.jpg?width=500&amp;amp;height=642&amp;amp;face=0_0_500_642,https://scrap.kakaocdn.net/dn/ya4C4/hyRImjRIel/ssNOobha6CpPHrwGOhtAk1/img.jpg?width=500&amp;amp;height=642&amp;amp;face=0_0_500_642&quot;&gt;&lt;a href=&quot;https://www.aladin.co.kr/shop/wproduct.aspx?ItemId=307683870&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://www.aladin.co.kr/shop/wproduct.aspx?ItemId=307683870&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/vkJEu/hyRJTAlYqm/gDQoLXoxrU6Rs9pmBxXnGK/img.jpg?width=500&amp;amp;height=642&amp;amp;face=0_0_500_642,https://scrap.kakaocdn.net/dn/ya4C4/hyRImjRIel/ssNOobha6CpPHrwGOhtAk1/img.jpg?width=500&amp;amp;height=642&amp;amp;face=0_0_500_642');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;러닝 타입스크립트&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;자바스크립트 세계를 정복한 타입스크립트는 강력한 타입 안정성에 힘입어 가장 빠르게 성장하고 있다. 언어의 역사를 살펴보며 진화 과정과 작동 방식을 이해하고, 개념 설명을 돕는 수많은&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;www.aladin.co.kr&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Books/Learning TypeScript</category>
      <category>Never</category>
      <category>Typescript</category>
      <category>void</category>
      <category>러닝타입스크립트</category>
      <category>타입스크립트</category>
      <category>함수타입</category>
      <author>후끈후끈</author>
      <guid isPermaLink="true">https://likelacoste.tistory.com/63</guid>
      <comments>https://likelacoste.tistory.com/63#entry63comment</comments>
      <pubDate>Tue, 21 Feb 2023 00:24:30 +0900</pubDate>
    </item>
    <item>
      <title>3. 객체</title>
      <link>https://likelacoste.tistory.com/62</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;객체 타입&lt;/span&gt;&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;객체 리터럴은 중괄호({&amp;hellip;}) 사용하여 생성할 수 있는데, 타입스크립트는 객체의 각각의 키에 대한 값에 따라 타입을 결정하게 됩니다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;1.png&quot; data-origin-width=&quot;1406&quot; data-origin-height=&quot;652&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Znvr8/btrZLUsrtFG/K9hd1F0eDRIusHcJttH4jk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Znvr8/btrZLUsrtFG/K9hd1F0eDRIusHcJttH4jk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Znvr8/btrZLUsrtFG/K9hd1F0eDRIusHcJttH4jk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FZnvr8%2FbtrZLUsrtFG%2FK9hd1F0eDRIusHcJttH4jk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;666&quot; height=&quot;309&quot; data-filename=&quot;1.png&quot; data-origin-width=&quot;1406&quot; data-origin-height=&quot;652&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;객체 타입 선언&lt;/span&gt;&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;객체 타입은 객체 리터럴과 유사하게 보이지만 값 대신 타입을 사용하여 설명합니다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;2.png&quot; data-origin-width=&quot;1392&quot; data-origin-height=&quot;724&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bhTSUC/btrZJC0CUjK/kS7jUyLvA9IDu5N4ukWFFK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bhTSUC/btrZJC0CUjK/kS7jUyLvA9IDu5N4ukWFFK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bhTSUC/btrZJC0CUjK/kS7jUyLvA9IDu5N4ukWFFK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbhTSUC%2FbtrZJC0CUjK%2FkS7jUyLvA9IDu5N4ukWFFK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;666&quot; height=&quot;346&quot; data-filename=&quot;2.png&quot; data-origin-width=&quot;1392&quot; data-origin-height=&quot;724&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&amp;nbsp;&lt;/h3&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;별칭 객체 타입&lt;/span&gt;&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;span style=&quot;background-color: #f6e199;&quot;&gt;&lt;b&gt;&amp;nbsp;{name: string, age: number} &lt;/b&gt;&lt;/span&gt;와 같은 객체 타입을 계속 작성하는 것은 효율적이지 못하고 귀찮습니다. 일반적으로는 각 객체 타입에 &lt;b&gt;타입 별칭&lt;/b&gt;을 할당하여 사용합니다. (대부분의 타입스크립트 프로젝트에서는 객체 타입을 설명할 때 &lt;b&gt;인터페이스(interface)&lt;/b&gt; 키워드를 사용하는 것을 선호)&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;3.png&quot; data-origin-width=&quot;1046&quot; data-origin-height=&quot;796&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ddijtU/btrZPT7EwaG/K0WlYwFnfDSCZ4TxniEfl0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ddijtU/btrZPT7EwaG/K0WlYwFnfDSCZ4TxniEfl0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ddijtU/btrZPT7EwaG/K0WlYwFnfDSCZ4TxniEfl0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FddijtU%2FbtrZPT7EwaG%2FK0WlYwFnfDSCZ4TxniEfl0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;666&quot; height=&quot;507&quot; data-filename=&quot;3.png&quot; data-origin-width=&quot;1046&quot; data-origin-height=&quot;796&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&amp;nbsp;&lt;/h2&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;구조적 타이핑&lt;/span&gt;&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;타입스크립트의 타입 시스템은 구조적으로 타입화(structurally typed)되어 있습니다. 즉, 타입을 충족하는 모든 값을 해당 타입의 값으로 사용할 수 있습니다.(타입 오류가 발생하지 않음)&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;4.png&quot; data-origin-width=&quot;1102&quot; data-origin-height=&quot;904&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/oS7PR/btrZJCl3gQ7/tmHkDvh68nUNGIGTfl8MJ1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/oS7PR/btrZJCl3gQ7/tmHkDvh68nUNGIGTfl8MJ1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/oS7PR/btrZJCl3gQ7/tmHkDvh68nUNGIGTfl8MJ1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FoS7PR%2FbtrZJCl3gQ7%2FtmHkDvh68nUNGIGTfl8MJ1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;666&quot; height=&quot;546&quot; data-filename=&quot;4.png&quot; data-origin-width=&quot;1102&quot; data-origin-height=&quot;904&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&amp;nbsp;&lt;/h4&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;사용 검사&lt;/span&gt;&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;객체 타입으로 &lt;a title=&quot;에노테이션&quot; href=&quot;https://likelacoste.tistory.com/61&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;에노테이션 &lt;/a&gt;된 위치에 값을 제공할 때 타입스크립트는 값을 해당 객체 타입에 할당 할 수 있는지 확인합니다. 할당하는 값에 객체 타입의 필수 속성을 가지고 있어야지, 만약 없다면 타입 오류를 발생합니다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;5.png&quot; data-origin-width=&quot;1334&quot; data-origin-height=&quot;940&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/NvoqJ/btrZQecQXiL/gsVS9LefZVIfWfrFQXu371/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/NvoqJ/btrZQecQXiL/gsVS9LefZVIfWfrFQXu371/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/NvoqJ/btrZQecQXiL/gsVS9LefZVIfWfrFQXu371/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FNvoqJ%2FbtrZQecQXiL%2FgsVS9LefZVIfWfrFQXu371%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;666&quot; height=&quot;469&quot; data-filename=&quot;5.png&quot; data-origin-width=&quot;1334&quot; data-origin-height=&quot;940&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;또한 둘 사이에 일치하지 않은 타입이 있어도 타입 오류를 발생합니다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;6.png&quot; data-origin-width=&quot;1102&quot; data-origin-height=&quot;580&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bzVkiL/btrZK2qM2AX/P37rRy4T9rQ1pf7egckIE0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bzVkiL/btrZK2qM2AX/P37rRy4T9rQ1pf7egckIE0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bzVkiL/btrZK2qM2AX/P37rRy4T9rQ1pf7egckIE0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbzVkiL%2FbtrZK2qM2AX%2FP37rRy4T9rQ1pf7egckIE0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;666&quot; height=&quot;351&quot; data-filename=&quot;6.png&quot; data-origin-width=&quot;1102&quot; data-origin-height=&quot;580&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;객체 타입은 &lt;span style=&quot;background-color: #9feec3;&quot;&gt;&amp;nbsp;필수 속성 이름 &lt;/span&gt;과 &lt;span style=&quot;background-color: #9feec3;&quot;&gt;&amp;nbsp;해당 속성 &lt;/span&gt;이 예상되는 타입을 모두 지정하기 때문에 객체의 속성이 일치하지 않으면 타입스크립트는 타입 오류를 발생합니다.&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&amp;nbsp;&lt;/h3&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;초과 속성 검사&lt;/span&gt;&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;변수가 객체 타입으로 선언되고, 초기값에 객체 타입에서 정의된 것보다 많은 필드가 있다면 타입스크립트는 타입 오류를 발생합니다. 변수를 객체 타입으로 선언하는 것은 타입 검사기가 해당 타입에 예상되는 필드만 있는지 확인하는 방법이기도 합니다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;7.png&quot; data-origin-width=&quot;1162&quot; data-origin-height=&quot;760&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Y8vPY/btrZJXpWLj9/GHnG0FGl8dk7XewY608kwk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Y8vPY/btrZJXpWLj9/GHnG0FGl8dk7XewY608kwk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Y8vPY/btrZJXpWLj9/GHnG0FGl8dk7XewY608kwk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FY8vPY%2FbtrZJXpWLj9%2FGHnG0FGl8dk7XewY608kwk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;666&quot; height=&quot;436&quot; data-filename=&quot;7.png&quot; data-origin-width=&quot;1162&quot; data-origin-height=&quot;760&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;초과 속성 검사는 &lt;b&gt;객체 타입으로 선언된 위치에서 생성되는 객체 리터럴에 대해서만&lt;/b&gt; 일어납니다. 기존 객체 리터럴을 제공하면 초과 속성 검사를 우회하기 때문에 타입 오류가 발생하지 않습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;8.png&quot; data-origin-width=&quot;974&quot; data-origin-height=&quot;724&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dKubyg/btrZISiqSaw/KZ2zZCDJiGPAWkBdcoaaW1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dKubyg/btrZISiqSaw/KZ2zZCDJiGPAWkBdcoaaW1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dKubyg/btrZISiqSaw/KZ2zZCDJiGPAWkBdcoaaW1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdKubyg%2FbtrZISiqSaw%2FKZ2zZCDJiGPAWkBdcoaaW1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;666&quot; height=&quot;495&quot; data-filename=&quot;8.png&quot; data-origin-width=&quot;974&quot; data-origin-height=&quot;724&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;객체 타입에 선언되지 않은 초과 속성은 예상하지 않은 데이터 값을 갖게 되어 &lt;b&gt;예상하는 대로 작동하지 않을 수도&lt;/b&gt; 있습니다.&lt;/span&gt; (초과 속성을 비활성화하면 코드를 깨끗하게 유지할 수 있고, 예상한 대로 작동하도록 만들 수 있습니다.)&lt;/span&gt;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&amp;nbsp;&lt;/h3&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;중첩된 객체 타입&lt;/span&gt;&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;타입스크립트의 객체 타입도 자바스크립트 객체와 같이 타입 시스템에서 중첩된 객체 타입을 나타낼 수 있습니다. 그리고 중첩된 타입을 자체 타입 별칭으로 추출하는 방법도 있습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;9.png&quot; data-origin-width=&quot;1364&quot; data-origin-height=&quot;1408&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/laYNu/btrZKZ1Pma6/Q9N47zxdUz0NIgpMdkOLnK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/laYNu/btrZKZ1Pma6/Q9N47zxdUz0NIgpMdkOLnK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/laYNu/btrZKZ1Pma6/Q9N47zxdUz0NIgpMdkOLnK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FlaYNu%2FbtrZKZ1Pma6%2FQ9N47zxdUz0NIgpMdkOLnK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;666&quot; height=&quot;687&quot; data-filename=&quot;9.png&quot; data-origin-width=&quot;1364&quot; data-origin-height=&quot;1408&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;이처럼 중첩된 객체 타입을 고유한 이름으로 바꿔서 사용하면 코드와 오류 메시지가 더 읽기 쉬워집니다.&lt;/span&gt;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&amp;nbsp;&lt;/h3&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;선택적 속성&lt;/span&gt;&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;타입의 속성 에노테이션에서&amp;nbsp;&lt;b&gt;&lt;span style=&quot;background-color: #f6e199;&quot;&gt; :&amp;nbsp;&lt;/span&gt; 앞에&amp;nbsp;&lt;span style=&quot;background-color: #f6e199;&quot;&gt; ? &lt;/span&gt;를 추가하면 선택적 속성임&lt;/b&gt;을 나타낼 수 있습니다. 선택적 속성은 모든 객체에 객체 타입 속성 중 &lt;b&gt;생략하고 싶은 속성이나 존재하지 않아도 되는 속성에 대해 사용&lt;/b&gt;합니다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;10.png&quot; data-origin-width=&quot;1234&quot; data-origin-height=&quot;1012&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/BYpo5/btrZIFjqwbB/BkrRsCdDG0kPU7deQuX4R0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/BYpo5/btrZIFjqwbB/BkrRsCdDG0kPU7deQuX4R0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/BYpo5/btrZIFjqwbB/BkrRsCdDG0kPU7deQuX4R0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FBYpo5%2FbtrZIFjqwbB%2FBkrRsCdDG0kPU7deQuX4R0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;666&quot; height=&quot;546&quot; data-filename=&quot;10.png&quot; data-origin-width=&quot;1234&quot; data-origin-height=&quot;1012&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;선택적 속성과 undefined를 포함한 유니언 타입은 서로 다릅니다.&amp;nbsp;&lt;/b&gt;&lt;/span&gt;&lt;span style=&quot;background-color: #f6e199;&quot;&gt;&lt;b&gt; ?&lt;/b&gt; &lt;/span&gt;를 사용해 선택적으로 선언된 속성은 존재하지 않아도 됩니다. 하지만 필수로 &lt;span style=&quot;background-color: #f6e199;&quot;&gt;&lt;b&gt;선언된 속성과&lt;/b&gt;&lt;/span&gt;&lt;span style=&quot;background-color: #ffc1c8;&quot;&gt;&lt;b&gt;&lt;span style=&quot;background-color: #f6e199;&quot;&gt; | undefined&amp;nbsp;&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;b&gt; &lt;/b&gt;는 그 값이 undefined일지라도 &lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;반드시 존재&lt;/b&gt;&lt;/span&gt;해야 합니다.&lt;/span&gt;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&amp;nbsp;&lt;/h2&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;객체 타입 유니언&lt;/span&gt;&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;객체 타입의 조합을 명시하면 객체 타입을 더 명확하게 정의 할 수 있습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;11.png&quot; data-origin-width=&quot;1638&quot; data-origin-height=&quot;940&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/w7vWD/btrZK25mYQD/2wpq1Kp4TiWL7VDxJsra2K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/w7vWD/btrZK25mYQD/2wpq1Kp4TiWL7VDxJsra2K/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/w7vWD/btrZK25mYQD/2wpq1Kp4TiWL7VDxJsra2K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fw7vWD%2FbtrZK25mYQD%2F2wpq1Kp4TiWL7VDxJsra2K%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;666&quot; height=&quot;382&quot; data-filename=&quot;11.png&quot; data-origin-width=&quot;1638&quot; data-origin-height=&quot;940&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;위 코드를 보면 age와 gender는 항상 존재한다는 보장을 할 수 없는 속성입니다. 이때 타입스크립트는 해당 속성의 타입을 선택적 타입으로 유추하게 됩니다.&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;typescript&quot; data-ke-language=&quot;typescript&quot;&gt;&lt;code&gt;const person = Math.random() &amp;gt; 0.5 
						? {name: 'Kim', age: 31} 
						: {name: 'Kim', gender: 'male'};

/*
타입 :
{name: string; age: number; gender?: undefined;}
| {name: string; gender: string; age?: undefined;} 
*/

person.name // 타입: string
person.age // 타입: number | undefined
person.gender // 타입: string | undefined&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;값이 여러 타입 중 하나일 경우, 모든 타입에 존재하지 않는 속성이 객체에 존재할 거라고 보장할 수 없습니다. 잠재적으로 존재하지 않은 객체의 속성에 대한 접근을 제한하면 코드의 안전을 지킬 수 있습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;타입 검사기가 유니언 타입 값에 특정 속성이 포함된 경우에만 코드 영역을 실행할 수 있음을 알게 되면, 값의 타입을 해당 속성을 포함하는 구성 요소로만 좁힙니다. &lt;a title=&quot;(내로잉)&quot; href=&quot;https://likelacoste.tistory.com/61&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;(내로잉)&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;12.png&quot; data-origin-width=&quot;1622&quot; data-origin-height=&quot;616&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bk9PKF/btrZJ3DMUHm/CsPP19OKrkE2Xn7Aqw8lI0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bk9PKF/btrZJ3DMUHm/CsPP19OKrkE2Xn7Aqw8lI0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bk9PKF/btrZJ3DMUHm/CsPP19OKrkE2Xn7Aqw8lI0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbk9PKF%2FbtrZJ3DMUHm%2FCsPP19OKrkE2Xn7Aqw8lI0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;666&quot; height=&quot;253&quot; data-filename=&quot;12.png&quot; data-origin-width=&quot;1622&quot; data-origin-height=&quot;616&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;타입스크립는 존재하지 않는 객체의 속성에 접근하려고 시도하면 타입 오류로 간주하게 됩니다. 그렇기 때문에&amp;nbsp;&lt;span style=&quot;background-color: #99cefa;&quot;&gt;&lt;b&gt; if(person.age)&amp;nbsp; &lt;/b&gt;&lt;/span&gt;와 같은 형식으로 참 여부를 확인 하는 것을 허용하지 않습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;타입스크립트에서 &lt;b&gt;객체의 속성이 객체의 형태를 나타내도록 하는 형태&lt;/b&gt;를 판별된 유니언이라고 부르고, 객체의 타입을 가리키는 속성을 &lt;b&gt;판별값&lt;/b&gt;이라고 합니다.(타입스크립트는 코드에서 판별 속성을 사용해 타입 내로잉을 수행)&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;13.png&quot; data-origin-width=&quot;1262&quot; data-origin-height=&quot;1156&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/FF1n5/btrZK2j143v/YBYOW7iDU9FevGvbjFDzck/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/FF1n5/btrZK2j143v/YBYOW7iDU9FevGvbjFDzck/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/FF1n5/btrZK2j143v/YBYOW7iDU9FevGvbjFDzck/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FFF1n5%2FbtrZK2j143v%2FYBYOW7iDU9FevGvbjFDzck%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;666&quot; height=&quot;610&quot; data-filename=&quot;13.png&quot; data-origin-width=&quot;1262&quot; data-origin-height=&quot;1156&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&amp;nbsp;&lt;/h2&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;교차 타입&lt;/span&gt;&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;타입스크립트에서 &lt;b&gt;&amp;amp; 교차타입(intersection type)&lt;/b&gt;을 사용해 &lt;b&gt;여러 타입을 동시에&lt;/b&gt; 나타낼 수 있습니다. 교차 타입은 일반적으로 여러 개의 기존 객체 타입을 별칭 객체 타입으로 결합해 새로운 타입을 생성합니다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;14.png&quot; data-origin-width=&quot;946&quot; data-origin-height=&quot;940&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bobtay/btrZJDZCcGq/2tcyobXng1jiYHuUAWOfwk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bobtay/btrZJDZCcGq/2tcyobXng1jiYHuUAWOfwk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bobtay/btrZJDZCcGq/2tcyobXng1jiYHuUAWOfwk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbobtay%2FbtrZJDZCcGq%2F2tcyobXng1jiYHuUAWOfwk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;666&quot; height=&quot;662&quot; data-filename=&quot;14.png&quot; data-origin-width=&quot;946&quot; data-origin-height=&quot;940&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;교차 타입은 유용한 개념이지만, 사용자나 타입스크립트 컴파일러를 혼동시키기 쉽습니다. 그렇기 때문에 교차 타입을 사용할 때는 가능한 코드를 간결하게 유지해야 합니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;never&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;원시 타입의 값&lt;/b&gt;은 동시에 여러 타입이 될 수 없기 때문에 &lt;b&gt;교차 타입의 구성 요소로 함께 결합할 수 없습니다.&lt;/b&gt; 만약 두개의 원시 타입을 교차 타입으로 결합하는 경우 &lt;span style=&quot;background-color: #9feec3;&quot;&gt;&lt;b&gt;never&lt;/b&gt;&lt;/span&gt; 키워드로 표시되어 &lt;span style=&quot;background-color: #9feec3;&quot;&gt;&lt;b&gt;never&lt;/b&gt;&lt;/span&gt; 타입이 됩니다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;15.png&quot; data-origin-width=&quot;1016&quot; data-origin-height=&quot;544&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/7ZzFm/btrZNt9go6t/QEpTycv3MZr6gurCM0PMF1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/7ZzFm/btrZNt9go6t/QEpTycv3MZr6gurCM0PMF1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/7ZzFm/btrZNt9go6t/QEpTycv3MZr6gurCM0PMF1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F7ZzFm%2FbtrZNt9go6t%2FQEpTycv3MZr6gurCM0PMF1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;666&quot; height=&quot;357&quot; data-filename=&quot;15.png&quot; data-origin-width=&quot;1016&quot; data-origin-height=&quot;544&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;이러한 &lt;span style=&quot;background-color: #9feec3;&quot;&gt;&lt;b&gt;never&lt;/b&gt;&lt;/span&gt; 키워드와 &lt;span style=&quot;background-color: #9feec3;&quot;&gt;&lt;b&gt;never&lt;/b&gt;&lt;/span&gt; 타입은 그 어떠한 타입도 제공할 수 없습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.aladin.co.kr/shop/wproduct.aspx?ItemId=307683870&quot;&gt;https://www.aladin.co.kr/shop/wproduct.aspx?ItemId=307683870&lt;/a&gt;&lt;span style=&quot;background-color: #ffffff; color: #000000;&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1676772592984&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;books.book&quot; data-og-title=&quot;러닝 타입스크립트&quot; data-og-description=&quot;자바스크립트 세계를 정복한 타입스크립트는 강력한 타입 안정성에 힘입어 가장 빠르게 성장하고 있다. 언어의 역사를 살펴보며 진화 과정과 작동 방식을 이해하고, 개념 설명을 돕는 수많은 &quot; data-og-host=&quot;www.aladin.co.kr&quot; data-og-source-url=&quot;https://www.aladin.co.kr/shop/wproduct.aspx?ItemId=307683870&quot; data-og-url=&quot;https://www.aladin.co.kr/shop/wproduct.aspx?ItemId=307683870&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/bOfWQu/hyRF8kF9d8/AAakrGYinqsyIDX6OQGkbk/img.jpg?width=500&amp;amp;height=642&amp;amp;face=0_0_500_642,https://scrap.kakaocdn.net/dn/b4rKpC/hyRGeLYok4/mYxxKc1KzKz5tF843dgT30/img.jpg?width=500&amp;amp;height=642&amp;amp;face=0_0_500_642&quot;&gt;&lt;a href=&quot;https://www.aladin.co.kr/shop/wproduct.aspx?ItemId=307683870&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://www.aladin.co.kr/shop/wproduct.aspx?ItemId=307683870&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/bOfWQu/hyRF8kF9d8/AAakrGYinqsyIDX6OQGkbk/img.jpg?width=500&amp;amp;height=642&amp;amp;face=0_0_500_642,https://scrap.kakaocdn.net/dn/b4rKpC/hyRGeLYok4/mYxxKc1KzKz5tF843dgT30/img.jpg?width=500&amp;amp;height=642&amp;amp;face=0_0_500_642');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;러닝 타입스크립트&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;자바스크립트 세계를 정복한 타입스크립트는 강력한 타입 안정성에 힘입어 가장 빠르게 성장하고 있다. 언어의 역사를 살펴보며 진화 과정과 작동 방식을 이해하고, 개념 설명을 돕는 수많은&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;www.aladin.co.kr&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;</description>
      <category>Books/Learning TypeScript</category>
      <category>object type</category>
      <category>Typescript</category>
      <category>객체타입</category>
      <category>러닝타입스크립트</category>
      <category>타입스크립트</category>
      <author>후끈후끈</author>
      <guid isPermaLink="true">https://likelacoste.tistory.com/62</guid>
      <comments>https://likelacoste.tistory.com/62#entry62comment</comments>
      <pubDate>Sat, 18 Feb 2023 14:22:25 +0900</pubDate>
    </item>
    <item>
      <title>2. 유니언과 리터럴</title>
      <link>https://likelacoste.tistory.com/61</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;유니언과 내로잉은 타입스크립트가 해당 값을 바탕으로 타입 추론을 수행하는 핵심 개념입니다.(코드 정보에 입각한 추론)&lt;/span&gt;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;유니언과 리터럴&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;- 유니언(union) : 값에 허용된 타입을 두 개 이상의 가능한 타입으로 확장하는 것&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;- 내로잉(narrowing) : 값에 허용된 타입이 하나 이상의 가능한 타입이 되지 않도록 좁히는 것&lt;/span&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&amp;nbsp;&lt;/h2&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;1️⃣ 유니언 타입&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;유니언 타입은 (값이 정확히 어떤 타입인지 모르지만) &lt;b&gt;두 개 이상의 타입을 지정&lt;/b&gt;하는 것을 말합니다. 유니언 타입은 가능한 값 또는 구성 요소 사이에 &lt;b&gt;수직선(|) 연산자를 사용&lt;/b&gt;하여 지정합니다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2023-02-15 17.21.49.png&quot; data-origin-width=&quot;1118&quot; data-origin-height=&quot;214&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/J4gbY/btrZAfKpamy/9ipy9HrG1vMBad6AQIwkPK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/J4gbY/btrZAfKpamy/9ipy9HrG1vMBad6AQIwkPK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/J4gbY/btrZAfKpamy/9ipy9HrG1vMBad6AQIwkPK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FJ4gbY%2FbtrZAfKpamy%2F9ipy9HrG1vMBad6AQIwkPK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;666&quot; height=&quot;127&quot; data-filename=&quot;스크린샷 2023-02-15 17.21.49.png&quot; data-origin-width=&quot;1118&quot; data-origin-height=&quot;214&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&amp;nbsp;&lt;/h3&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;유니언 속성&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;값이 유니언 타입인 경우, 타입스크립트는 유니언으로 선언한 &lt;b&gt;모든 타입에 존재하는 멤버 속성만&lt;/b&gt; 접근 할 수 있습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2023-02-15 17.27.51.png&quot; data-origin-width=&quot;1086&quot; data-origin-height=&quot;528&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/t0uXy/btrZxdGQLpV/YZgGgunMizXe6mXLOrSae0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/t0uXy/btrZxdGQLpV/YZgGgunMizXe6mXLOrSae0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/t0uXy/btrZxdGQLpV/YZgGgunMizXe6mXLOrSae0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Ft0uXy%2FbtrZxdGQLpV%2FYZgGgunMizXe6mXLOrSae0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;666&quot; height=&quot;324&quot; data-filename=&quot;스크린샷 2023-02-15 17.27.51.png&quot; data-origin-width=&quot;1086&quot; data-origin-height=&quot;528&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;유니언 타입의 경우 타입이 두 개 이상이기 때문에 해당 변수가 어떤 타입인지 확실하게 알려지지 않은 경우, 타입스크립트는 해당 속성을 사용하는 것을 안전하지 않다고 여기게 되어 에러가 발생하게 됩니다. 이는 모든 유니언 타입에 존재하지 않는 속성에 대해 접근을 제한하는 것에 대한 타입스크립트의 안전 조치에 해당됩니다.&lt;/span&gt;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&amp;nbsp;&lt;/h2&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;2️⃣ 내로잉&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;내로잉은 값이 정의, 선언 혹은 이전에 유추된 것보다 더 구체적인 타입임을 코드에서 유추하는 것을 말합니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;타입스크립트는 값의 타입이 이전에 알려진 것보다 더 좁혀진 것을 알게 되면 값을 더 구체적인 타입으로 취급하게 되는데, 타입을 좁히는데 사용할 수 있는 논리적 검사를 &lt;b&gt;타입가드(type guard)&lt;/b&gt;라고 합니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;값 할당을 통한 내로잉&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;변수에 직접 값을 할당&lt;/b&gt;하게 되면 타입스크립트는 &lt;b&gt;변수의 타입을 할당된 값의 타입&lt;/b&gt;으로 좁히게 됩니다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2023-02-15 18.28.44.png&quot; data-origin-width=&quot;886&quot; data-origin-height=&quot;356&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/c5iDUT/btrZBsWL3r7/GvXJXichcFHqGRSAftkV41/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/c5iDUT/btrZBsWL3r7/GvXJXichcFHqGRSAftkV41/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/c5iDUT/btrZBsWL3r7/GvXJXichcFHqGRSAftkV41/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fc5iDUT%2FbtrZBsWL3r7%2FGvXJXichcFHqGRSAftkV41%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;666&quot; height=&quot;268&quot; data-filename=&quot;스크린샷 2023-02-15 18.28.44.png&quot; data-origin-width=&quot;886&quot; data-origin-height=&quot;356&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;변수 &lt;b&gt;&lt;span style=&quot;background-color: #9feec3;&quot;&gt;person&lt;/span&gt;&lt;/b&gt;은 &lt;span style=&quot;background-color: #c1bef9;&quot;&gt;&lt;b&gt;number | string&lt;/b&gt;&lt;/span&gt; 타입으로 선언되었지만, 문자열 &lt;span style=&quot;background-color: #f6e199;&quot;&gt;&lt;b&gt;Kim&lt;/b&gt;&lt;/span&gt;이 할당되면서 타입스크립트는 해당 변수를 &lt;span style=&quot;background-color: #c1bef9;&quot;&gt;&lt;b&gt;string&lt;/b&gt;&lt;/span&gt; 타입으로 좁혀지는 것을 볼 수 있다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;조건 검사를 통한 내로잉&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;타입스크립트는 if 문 안에서 변수가 알려진 값과 동일한 타입인지를 확인하여 변수의 값을 좁히는 방법을 사용합니다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2023-02-15 18.35.19.png&quot; data-origin-width=&quot;1088&quot; data-origin-height=&quot;398&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/r3LqC/btrZAutVnli/dgSbfTctT6ohLMiJIe3GM0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/r3LqC/btrZAutVnli/dgSbfTctT6ohLMiJIe3GM0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/r3LqC/btrZAutVnli/dgSbfTctT6ohLMiJIe3GM0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fr3LqC%2FbtrZAutVnli%2FdgSbfTctT6ohLMiJIe3GM0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;666&quot; height=&quot;244&quot; data-filename=&quot;스크린샷 2023-02-15 18.35.19.png&quot; data-origin-width=&quot;1088&quot; data-origin-height=&quot;398&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&amp;nbsp;&lt;/h3&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;typeof 검사를 통한 내로잉&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;타입스크립트는 직접 값을 확인해 타입을 좁히기도 하지만, typeof 연산자를 사용할 수 도 있습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2023-02-15 18.41.28.png&quot; data-origin-width=&quot;1126&quot; data-origin-height=&quot;552&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bm6dS2/btrZA2KHbN4/KQANyBn9OSoptQoPsRdDE0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bm6dS2/btrZA2KHbN4/KQANyBn9OSoptQoPsRdDE0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bm6dS2/btrZA2KHbN4/KQANyBn9OSoptQoPsRdDE0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbm6dS2%2FbtrZA2KHbN4%2FKQANyBn9OSoptQoPsRdDE0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;666&quot; height=&quot;326&quot; data-filename=&quot;스크린샷 2023-02-15 18.41.28.png&quot; data-origin-width=&quot;1126&quot; data-origin-height=&quot;552&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;3️⃣ &lt;b&gt;리터럴 타입&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;리터럴 타입은 원시 타입 중 하나의 타입을 할당하는 것이 아니라 &lt;b&gt;변수나 매개변수에 정확한 값을 설정하는 것&lt;/b&gt;을 의미합니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;변수를 const로 선언하고 값을 할당하면 &lt;b&gt;타입스크립트는 해당 변수를 할당된 리터럴 값으로 유추&lt;/b&gt;하게되어, 일반적인 원시 타입 대신 변수의 값을 리터럴로 설정하게 됩니다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2023-02-15 19.08.56.png&quot; data-origin-width=&quot;478&quot; data-origin-height=&quot;154&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dv1rdV/btrZzGocrDz/JUdhmV38hLlm87dN6Tp2Q1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dv1rdV/btrZzGocrDz/JUdhmV38hLlm87dN6Tp2Q1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dv1rdV/btrZzGocrDz/JUdhmV38hLlm87dN6Tp2Q1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fdv1rdV%2FbtrZzGocrDz%2FJUdhmV38hLlm87dN6Tp2Q1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;444&quot; height=&quot;143&quot; data-filename=&quot;스크린샷 2023-02-15 19.08.56.png&quot; data-origin-width=&quot;478&quot; data-origin-height=&quot;154&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;유니언 타입 에노테이션을 리터럴과 원시 타입을 섞어서 사용할 수 있습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2023-02-15 19.12.54.png&quot; data-origin-width=&quot;1070&quot; data-origin-height=&quot;292&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cuJhnW/btrZuCGVEZF/cFVDKhKRtQ0Ak88jlv0pb0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cuJhnW/btrZuCGVEZF/cFVDKhKRtQ0Ak88jlv0pb0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cuJhnW/btrZuCGVEZF/cFVDKhKRtQ0Ak88jlv0pb0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcuJhnW%2FbtrZuCGVEZF%2FcFVDKhKRtQ0Ak88jlv0pb0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;666&quot; height=&quot;182&quot; data-filename=&quot;스크린샷 2023-02-15 19.12.54.png&quot; data-origin-width=&quot;1070&quot; data-origin-height=&quot;292&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;4️⃣ 엄격한 null 검사&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;타입스크립트 컴파일러는 실행 방식을 변경할 수 있는 다양한 옵션을 제공하는데, 그 중에 가장 유용한 옵션 중 하나인 &lt;b&gt;&lt;span style=&quot;background-color: #ffc9af;&quot;&gt;strictNullChecks&lt;/span&gt;&lt;/b&gt;는 &lt;b&gt;엄격한 null 검사&lt;/b&gt;를 활성화 시킬지 여부를 결정합니다. &lt;span style=&quot;background-color: #ffc9af;&quot;&gt;&lt;b&gt;strictNullChecks&lt;/b&gt;&lt;/span&gt; 옵션을 비활성화 하면 코드의 모든 타입에 &lt;span style=&quot;background-color: #f6e199;&quot;&gt;&lt;b&gt;| null | undefined&lt;/b&gt;&lt;/span&gt; 를 추가해야 모든 변수가 &lt;span style=&quot;background-color: #f6e199;&quot;&gt;&lt;b&gt;null&lt;/b&gt;&lt;/span&gt; 또는 &lt;span style=&quot;background-color: #f6e199;&quot;&gt;&lt;b&gt;undefined&lt;/b&gt;&lt;/span&gt;를 할당할 수 있게 됩니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;strictNullChecks을 false로 설정하게 되면 아래의 코드가 안전하다고 간주됩니다.(오류가 발생하지 않음)&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2023-02-15 19.25.03.png&quot; data-origin-width=&quot;878&quot; data-origin-height=&quot;170&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cGpbaC/btrZAspwOHQ/Lifh6W1aFQUrL5aVICqwS0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cGpbaC/btrZAspwOHQ/Lifh6W1aFQUrL5aVICqwS0/img.png&quot; data-alt=&quot;strictNullChecks : false&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cGpbaC/btrZAspwOHQ/Lifh6W1aFQUrL5aVICqwS0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcGpbaC%2FbtrZAspwOHQ%2FLifh6W1aFQUrL5aVICqwS0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;666&quot; height=&quot;129&quot; data-filename=&quot;스크린샷 2023-02-15 19.25.03.png&quot; data-origin-width=&quot;878&quot; data-origin-height=&quot;170&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;strictNullChecks : false&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;반면에 true로 설정하는 경우, 코드가 null 또는 undefined 값으로 인한 오류로부터 안전한지 여부를 쉽게 파악할 수 있습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2023-02-15 19.25.59.png&quot; data-origin-width=&quot;864&quot; data-origin-height=&quot;192&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/K4Poj/btrZAGnFTFJ/kuOKnltdPGcX2YgCpqEmA1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/K4Poj/btrZAGnFTFJ/kuOKnltdPGcX2YgCpqEmA1/img.png&quot; data-alt=&quot;strictNullChecks : true&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/K4Poj/btrZAGnFTFJ/kuOKnltdPGcX2YgCpqEmA1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FK4Poj%2FbtrZAGnFTFJ%2FkuOKnltdPGcX2YgCpqEmA1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;666&quot; height=&quot;148&quot; data-filename=&quot;스크린샷 2023-02-15 19.25.59.png&quot; data-origin-width=&quot;864&quot; data-origin-height=&quot;192&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;strictNullChecks : true&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;참 검사를 통한 내로잉&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;타입스크립트는 잠재적인 값 중에 &lt;span style=&quot;background-color: #9feec3;&quot;&gt;&lt;b&gt;truthy&lt;/b&gt;&lt;/span&gt;로 확인된 일부에 한해서만 변수의 타입을 좁힐 수 있습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2023-02-15 19.38.28.png&quot; data-origin-width=&quot;870&quot; data-origin-height=&quot;352&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/BzLJk/btrZzoOXrUS/z4LGTmFietxlpjkdwSiS7K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/BzLJk/btrZzoOXrUS/z4LGTmFietxlpjkdwSiS7K/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/BzLJk/btrZzoOXrUS/z4LGTmFietxlpjkdwSiS7K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FBzLJk%2FbtrZzoOXrUS%2Fz4LGTmFietxlpjkdwSiS7K%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;666&quot; height=&quot;269&quot; data-filename=&quot;스크린샷 2023-02-15 19.38.28.png&quot; data-origin-width=&quot;870&quot; data-origin-height=&quot;352&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2023-02-15 19.43.06.png&quot; data-origin-width=&quot;680&quot; data-origin-height=&quot;312&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/KZ2GP/btrZAhhnGQO/xDhdyveVCeAwjXYvo108T0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/KZ2GP/btrZAhhnGQO/xDhdyveVCeAwjXYvo108T0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/KZ2GP/btrZAhhnGQO/xDhdyveVCeAwjXYvo108T0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FKZ2GP%2FbtrZAhhnGQO%2FxDhdyveVCeAwjXYvo108T0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;666&quot; height=&quot;306&quot; data-filename=&quot;스크린샷 2023-02-15 19.43.06.png&quot; data-origin-width=&quot;680&quot; data-origin-height=&quot;312&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;5️⃣ &lt;b&gt;타입 별칭&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;타입스크립트에는 재사용하는 타입에 더 쉬운 이름을 할당하는 &lt;b&gt;타입 별칭(type alias)&lt;/b&gt;이 있습니다. 타입 별칭은 &lt;span style=&quot;background-color: #ffc1c8;&quot;&gt;&lt;b&gt;type 새로운 이름 = 타입&lt;/b&gt;&lt;/span&gt; 형태를 갖습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;타입스크립트가 타입 별칭을 발경하면 해당 별칭이 참조하는 실제 타입을 입력한 것처럼 작동하게 됩니다.&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;typescript&quot;&gt;&lt;code&gt;let dataTypeFirst: boolean | number | string | null | undefined;
let dataTypeSecond: boolean | number | string | null | undefined;
let dataTypeThird: boolean | number | string | null | undefined;

type dataType = boolean | number | string | null | undefined;

let dataTypeFirst : dataType;
let dataTypeSecond : dataType;
let dataTypeThird : dataType;
&lt;/code&gt;&lt;/pre&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&amp;nbsp;&lt;/h3&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;타입 별칭 결합&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;타입 별칭은 다른 타입 별칭을 참조할 수 있습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2023-02-15 19.54.16.png&quot; data-origin-width=&quot;846&quot; data-origin-height=&quot;240&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/vZO22/btrZtrTfvqA/TfOYCiHtzvGdHQVXE1qKiK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/vZO22/btrZtrTfvqA/TfOYCiHtzvGdHQVXE1qKiK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/vZO22/btrZtrTfvqA/TfOYCiHtzvGdHQVXE1qKiK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FvZO22%2FbtrZtrTfvqA%2FTfOYCiHtzvGdHQVXE1qKiK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;666&quot; height=&quot;189&quot; data-filename=&quot;스크린샷 2023-02-15 19.54.16.png&quot; data-origin-width=&quot;846&quot; data-origin-height=&quot;240&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.aladin.co.kr/shop/wproduct.aspx?ItemId=307683870&quot;&gt;https://www.aladin.co.kr/shop/wproduct.aspx?ItemId=307683870&lt;/a&gt;&amp;nbsp;&lt;/p&gt;
&lt;figure id=&quot;og_1676541894947&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;books.book&quot; data-og-title=&quot;러닝 타입스크립트&quot; data-og-description=&quot;자바스크립트 세계를 정복한 타입스크립트는 강력한 타입 안정성에 힘입어 가장 빠르게 성장하고 있다. 언어의 역사를 살펴보며 진화 과정과 작동 방식을 이해하고, 개념 설명을 돕는 수많은 &quot; data-og-host=&quot;www.aladin.co.kr&quot; data-og-source-url=&quot;https://www.aladin.co.kr/shop/wproduct.aspx?ItemId=307683870&quot; data-og-url=&quot;https://www.aladin.co.kr/shop/wproduct.aspx?ItemId=307683870&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/6Pjuy/hyRDXqzPv0/RyRnNe0ZA1QrATHDLql1X1/img.jpg?width=500&amp;amp;height=642&amp;amp;face=0_0_500_642,https://scrap.kakaocdn.net/dn/MgLjA/hyRD59Y8mk/FnHkVf0aC05P2RoMT5pcnk/img.jpg?width=500&amp;amp;height=642&amp;amp;face=0_0_500_642&quot;&gt;&lt;a href=&quot;https://www.aladin.co.kr/shop/wproduct.aspx?ItemId=307683870&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://www.aladin.co.kr/shop/wproduct.aspx?ItemId=307683870&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/6Pjuy/hyRDXqzPv0/RyRnNe0ZA1QrATHDLql1X1/img.jpg?width=500&amp;amp;height=642&amp;amp;face=0_0_500_642,https://scrap.kakaocdn.net/dn/MgLjA/hyRD59Y8mk/FnHkVf0aC05P2RoMT5pcnk/img.jpg?width=500&amp;amp;height=642&amp;amp;face=0_0_500_642');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;러닝 타입스크립트&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;자바스크립트 세계를 정복한 타입스크립트는 강력한 타입 안정성에 힘입어 가장 빠르게 성장하고 있다. 언어의 역사를 살펴보며 진화 과정과 작동 방식을 이해하고, 개념 설명을 돕는 수많은&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;www.aladin.co.kr&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;</description>
      <category>Books/Learning TypeScript</category>
      <category>Typescript</category>
      <category>러닝 타입스크립트</category>
      <category>리터럴</category>
      <category>유니언</category>
      <category>타입스크립트</category>
      <author>후끈후끈</author>
      <guid isPermaLink="true">https://likelacoste.tistory.com/61</guid>
      <comments>https://likelacoste.tistory.com/61#entry61comment</comments>
      <pubDate>Thu, 16 Feb 2023 19:05:20 +0900</pubDate>
    </item>
    <item>
      <title>1. 타입 시스템</title>
      <link>https://likelacoste.tistory.com/60</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;타입스크립트는 &lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;자바스크립트 코드를 구조화&lt;/b&gt;&lt;/span&gt;하고, &lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;타입 안정성을 강화&lt;/b&gt;&lt;/span&gt;하기 위해서 사용됩니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;타입의 종류&lt;/b&gt;&lt;/span&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;타입스트립트의 기본 타입은 자바스크립트의 기본 윈시 타입(primitive type)과 같습니다.&lt;/span&gt;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt;&lt;b&gt;윈시 타입(primitive type)&lt;/b&gt;&lt;br /&gt;- null&lt;br /&gt;- undefined&lt;br /&gt;- boolean&lt;br /&gt;- string&lt;br /&gt;- number&lt;br /&gt;- bigint&lt;br /&gt;- symbol&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;타입스크립트는 변수의 타입을 유추할 수 있어, 변수에 마우스를 올리면 해당 변수가 어떤 타입을 인지 유추한 정보를 메시지로 표시 됩니다.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2023-02-15 16.13.22.png&quot; data-origin-width=&quot;380&quot; data-origin-height=&quot;152&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/1BNd5/btrZmD0xiHr/ajI5X349DE6rKhIY2u2O1K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/1BNd5/btrZmD0xiHr/ajI5X349DE6rKhIY2u2O1K/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/1BNd5/btrZmD0xiHr/ajI5X349DE6rKhIY2u2O1K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F1BNd5%2FbtrZmD0xiHr%2FajI5X349DE6rKhIY2u2O1K%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;280&quot; height=&quot;112&quot; data-filename=&quot;스크린샷 2023-02-15 16.13.22.png&quot; data-origin-width=&quot;380&quot; data-origin-height=&quot;152&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;변수에 초기값이 없는 경우에는 어떻게 될까?&lt;/span&gt;&lt;/b&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;변수에 초기값이 없는 경우, 타입스크립트는 기본적으로 변수를 암묵적인 any 타입으로 간주합니다. any 타입은 특정 타입을 강제하는 대신 새로운 값이 할당될 때마다 변수 타입이 변합니다. 일반적으로 any 타입을 사용하게 되면 타입스크립트를 사용하는 목적이 사라지게 됩니다. &lt;span style=&quot;color: #ee2323;&quot;&gt;&lt;b&gt;(any 타입은 사용하지 말아야 합니다.)&lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&amp;nbsp;&lt;/h2&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;타입 에노테이션(Type Annotation)&lt;/span&gt;&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;타입스크립트는 초기값을 할당하지 않고도 변수의 타입을 선언할 수 있는 &lt;b&gt;타입 에노테이션&lt;/b&gt;을 제공합니다. 타입 에노테이션은 변수 이름 뒤에 콜론(:)을 붙인 후에 타입을 작성하여 사용 할 수 있습니다.&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;typescript&quot; data-ke-language=&quot;typescript&quot;&gt;&lt;code&gt;let myName: string;
myName = 'Kim';&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;타입 에노테이션은 타입스크립트에만 존재하기 때문에, 타입스크립트 소스 코드를 자바스크립트로 컴파일 하기 되면 해당 코드는 삭제되어 런타임 코드에 영향을 주지 않습니다.&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;typescript&quot; data-ke-language=&quot;typescript&quot;&gt;&lt;code&gt;// 출력된 .js 파일

let myName;
myName = 'Kim';&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;타입 에노테이션은 타입스크립트가 자체적으로 타입에 대한 정보를 얻을 수 없을 때나, 변동 될 가능성이 있는 변수에 사용하는 것이 좋습니다. (코드를 명확하게 문서화하거나 실수로 변수 타입이 변경되지 않도록 보호하기 위해 변수에 명시적으로 타입 에노테이션을 작성하는 것은 경우도 있습니다.)&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;cs&quot;&gt;&lt;code&gt;let myName:string = 'Kim'; // string 타입 에노테이션은 중복되었다.

// 타입스크립트는 myName을 string으로 선언하지 않아도 string 타입을 갖는 것을 예측할 수 있다.
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.aladin.co.kr/shop/wproduct.aspx?ItemId=307683870&quot;&gt;https://www.aladin.co.kr/shop/wproduct.aspx?ItemId=307683870&lt;/a&gt;&lt;span style=&quot;background-color: #ffffff; color: #000000;&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1676772725369&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;books.book&quot; data-og-title=&quot;러닝 타입스크립트&quot; data-og-description=&quot;자바스크립트 세계를 정복한 타입스크립트는 강력한 타입 안정성에 힘입어 가장 빠르게 성장하고 있다. 언어의 역사를 살펴보며 진화 과정과 작동 방식을 이해하고, 개념 설명을 돕는 수많은 &quot; data-og-host=&quot;www.aladin.co.kr&quot; data-og-source-url=&quot;https://www.aladin.co.kr/shop/wproduct.aspx?ItemId=307683870&quot; data-og-url=&quot;https://www.aladin.co.kr/shop/wproduct.aspx?ItemId=307683870&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/bOfWQu/hyRF8kF9d8/AAakrGYinqsyIDX6OQGkbk/img.jpg?width=500&amp;amp;height=642&amp;amp;face=0_0_500_642,https://scrap.kakaocdn.net/dn/b4rKpC/hyRGeLYok4/mYxxKc1KzKz5tF843dgT30/img.jpg?width=500&amp;amp;height=642&amp;amp;face=0_0_500_642&quot;&gt;&lt;a href=&quot;https://www.aladin.co.kr/shop/wproduct.aspx?ItemId=307683870&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://www.aladin.co.kr/shop/wproduct.aspx?ItemId=307683870&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/bOfWQu/hyRF8kF9d8/AAakrGYinqsyIDX6OQGkbk/img.jpg?width=500&amp;amp;height=642&amp;amp;face=0_0_500_642,https://scrap.kakaocdn.net/dn/b4rKpC/hyRGeLYok4/mYxxKc1KzKz5tF843dgT30/img.jpg?width=500&amp;amp;height=642&amp;amp;face=0_0_500_642');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;러닝 타입스크립트&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;자바스크립트 세계를 정복한 타입스크립트는 강력한 타입 안정성에 힘입어 가장 빠르게 성장하고 있다. 언어의 역사를 살펴보며 진화 과정과 작동 방식을 이해하고, 개념 설명을 돕는 수많은&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;www.aladin.co.kr&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;</description>
      <category>Books/Learning TypeScript</category>
      <category>Learning TypeScript</category>
      <category>running</category>
      <category>Typescript</category>
      <category>러닝 타입스크립트</category>
      <category>타입 시스템</category>
      <category>타입스크립트</category>
      <author>후끈후끈</author>
      <guid isPermaLink="true">https://likelacoste.tistory.com/60</guid>
      <comments>https://likelacoste.tistory.com/60#entry60comment</comments>
      <pubDate>Wed, 15 Feb 2023 20:21:37 +0900</pubDate>
    </item>
    <item>
      <title>[43] Exclude</title>
      <link>https://likelacoste.tistory.com/59</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000; background-color: #f6e199;&quot;&gt;&lt;b&gt;&amp;nbsp;문제&amp;nbsp;&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;&lt;code&gt;T&lt;/code&gt;에서 &lt;code&gt;U&lt;/code&gt;에 할당할 수 있는 타입을 제외하는 내장 제네릭 &lt;code&gt;Exclude&amp;lt;T, U&amp;gt;&lt;/code&gt;를 이를 사용하지 않고 구현하세요.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000; background-color: #f6e199;&quot;&gt;&lt;b&gt;&amp;nbsp;예시&amp;nbsp;&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;pre class=&quot;ada&quot;&gt;&lt;code&gt;type Result = MyExclude&amp;lt;'a' | 'b' | 'c', 'a'&amp;gt; // 'b' | 'c'&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;&lt;b&gt;  도전하기&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1669428075884&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;TS Playground - An online editor for exploring TypeScript and JavaScript&quot; data-og-description=&quot;The Playground lets you write TypeScript or JavaScript online in a safe and sharable way.&quot; data-og-host=&quot;www.typescriptlang.org&quot; data-og-source-url=&quot;https://www.typescriptlang.org/play?#code/PQKgUABBAsDMEFoIFEAeBjANgVwCYFNJEETSiAjATwgC0ALfRgOwHMIAKAAQC8HmWAlBADE+AIYBnasPLYAlpgAuCOUxHYmcgPZMiRYQYgBFbPgmLtuqEQCSAWwAOmfHfxNFERQwiyFy1SgYOAQAPAAqADQQAKoAfHpQsYFYePgQAGYATlp2EGGedFoSaYqUDmYFYh5imWmSEnIsTGLkzp5aMQkQAGJamRD4qGKOzgBcXQAGU4oSRKXlEABKZthKEAC8EACylGgpoQDkYgcQAD4QB+Qn5wfoB1FHB0nAwBdXZxd3RFMTXUkAanJ8AB3CA6CAAcTkigAEthyKMIHRFIoHBJRi8Zug6AA6ABWEhxfRYwDgYBAwDAVNAEAA+vSGYyGRAAJpabD9ADCWgIEBh+FqdKZwtpEApVPmaR2e2C+HCUTiGwgYiYlCpYBpIuFeTMHk5kgqWqZYspckcfQ8kogAG8UABHbBiTBRNDldAeAC+GWyuQOnElCGxTucrDMwGwFkwEgOErKaXQBokSoA2kRXfh3SFkA6nSFpUFUiFHh9LtdPvcLsdYg93jc7rFq2nUG7FFmc5g87sC4djiXa+WHr2bldq+WGxEmy2246O-n9nLzJlVGxzkxsHZyAKPux2EJ1kkAG5aOS4ARRboad2WUeL5cfNcbgXjsAAXXVGpAQqN9J6HK8W4AZUUfA0S-b8TQ-IgkgAugajSSh2X6CQtBwCwdHRJEUTRDFgCxXECSJTISTgYAVQkYEBSgiBARBCBkNQywMORVF0UxCRsXxQliVJWBgHoiNGKorY+jSTlYMwEMWDMRFmOwtiOII4lyUpMAgA&quot; data-og-url=&quot;https://www.typescriptlang.org/play/?&quot; data-og-image=&quot;&quot;&gt;&lt;a href=&quot;https://www.typescriptlang.org/play?#code/PQKgUABBAsDMEFoIFEAeBjANgVwCYFNJEETSiAjATwgC0ALfRgOwHMIAKAAQC8HmWAlBADE+AIYBnasPLYAlpgAuCOUxHYmcgPZMiRYQYgBFbPgmLtuqEQCSAWwAOmfHfxNFERQwiyFy1SgYOAQAPAAqADQQAKoAfHpQsYFYePgQAGYATlp2EGGedFoSaYqUDmYFYh5imWmSEnIsTGLkzp5aMQkQAGJamRD4qGKOzgBcXQAGU4oSRKXlEABKZthKEAC8EACylGgpoQDkYgcQAD4QB+Qn5wfoB1FHB0nAwBdXZxd3RFMTXUkAanJ8AB3CA6CAAcTkigAEthyKMIHRFIoHBJRi8Zug6AA6ABWEhxfRYwDgYBAwDAVNAEAA+vSGYyGRAAJpabD9ADCWgIEBh+FqdKZwtpEApVPmaR2e2C+HCUTiGwgYiYlCpYBpIuFeTMHk5kgqWqZYspckcfQ8kogAG8UABHbBiTBRNDldAeAC+GWyuQOnElCGxTucrDMwGwFkwEgOErKaXQBokSoA2kRXfh3SFkA6nSFpUFUiFHh9LtdPvcLsdYg93jc7rFq2nUG7FFmc5g87sC4djiXa+WHr2bldq+WGxEmy2246O-n9nLzJlVGxzkxsHZyAKPux2EJ1kkAG5aOS4ARRboad2WUeL5cfNcbgXjsAAXXVGpAQqN9J6HK8W4AZUUfA0S-b8TQ-IgkgAugajSSh2X6CQtBwCwdHRJEUTRDFgCxXECSJTISTgYAVQkYEBSgiBARBCBkNQywMORVF0UxCRsXxQliVJWBgHoiNGKorY+jSTlYMwEMWDMRFmOwtiOII4lyUpMAgA&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://www.typescriptlang.org/play?#code/PQKgUABBAsDMEFoIFEAeBjANgVwCYFNJEETSiAjATwgC0ALfRgOwHMIAKAAQC8HmWAlBADE+AIYBnasPLYAlpgAuCOUxHYmcgPZMiRYQYgBFbPgmLtuqEQCSAWwAOmfHfxNFERQwiyFy1SgYOAQAPAAqADQQAKoAfHpQsYFYePgQAGYATlp2EGGedFoSaYqUDmYFYh5imWmSEnIsTGLkzp5aMQkQAGJamRD4qGKOzgBcXQAGU4oSRKXlEABKZthKEAC8EACylGgpoQDkYgcQAD4QB+Qn5wfoB1FHB0nAwBdXZxd3RFMTXUkAanJ8AB3CA6CAAcTkigAEthyKMIHRFIoHBJRi8Zug6AA6ABWEhxfRYwDgYBAwDAVNAEAA+vSGYyGRAAJpabD9ADCWgIEBh+FqdKZwtpEApVPmaR2e2C+HCUTiGwgYiYlCpYBpIuFeTMHk5kgqWqZYspckcfQ8kogAG8UABHbBiTBRNDldAeAC+GWyuQOnElCGxTucrDMwGwFkwEgOErKaXQBokSoA2kRXfh3SFkA6nSFpUFUiFHh9LtdPvcLsdYg93jc7rFq2nUG7FFmc5g87sC4djiXa+WHr2bldq+WGxEmy2246O-n9nLzJlVGxzkxsHZyAKPux2EJ1kkAG5aOS4ARRboad2WUeL5cfNcbgXjsAAXXVGpAQqN9J6HK8W4AZUUfA0S-b8TQ-IgkgAugajSSh2X6CQtBwCwdHRJEUTRDFgCxXECSJTISTgYAVQkYEBSgiBARBCBkNQywMORVF0UxCRsXxQliVJWBgHoiNGKorY+jSTlYMwEMWDMRFmOwtiOII4lyUpMAgA&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url();&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;TS Playground - An online editor for exploring TypeScript and JavaScript&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;The Playground lets you write TypeScript or JavaScript online in a safe and sharable way.&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;www.typescriptlang.org&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000; background-color: #f6e199;&quot;&gt;&lt;b&gt;&amp;nbsp;풀이&amp;nbsp;&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;해당 문제를 풀기 위해서는 분산 조건부 타입에 대해서 알아야 한다. &lt;span style=&quot;background-color: #c1bef9;&quot;&gt;&lt;b&gt;&amp;nbsp;T&lt;/b&gt; &lt;/span&gt;가 유니온일 때 &lt;span style=&quot;background-color: #ffc9af;&quot;&gt;&lt;b&gt;&amp;nbsp;T extends U&amp;nbsp;&lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;와 같은 구조를 사용하면, TypeScript는 유니온 &lt;b&gt; &lt;span style=&quot;background-color: #c1bef9;&quot;&gt;&lt;b&gt;&amp;nbsp;T&lt;/b&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;&lt;/b&gt;를 순회하면서 각 원소들을 주어진 조건에 적용한다. &lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;예를들어 &lt;span style=&quot;background-color: #c1bef9;&quot;&gt;&lt;b&gt;&amp;nbsp;T&lt;/b&gt;&lt;span&gt; &lt;/span&gt;&lt;/span&gt;에 대한 타입 인수 &lt;span style=&quot;background-color: #ffc1c8;&quot;&gt;&lt;b&gt;&amp;nbsp;&lt;span style=&quot;color: #000000;&quot;&gt;A &lt;/span&gt;| B | C&amp;nbsp;&lt;/b&gt;&lt;/span&gt; 를사용하여 &lt;span style=&quot;background-color: #ffc9af;&quot;&gt;&lt;b&gt;&amp;nbsp;T extends U ? X : Y&lt;/b&gt; &lt;/span&gt;를 인스턴스화 하면 &lt;span style=&quot;background-color: #ffc9af;&quot;&gt;&lt;b&gt;&amp;nbsp;(A extends U ? X : Y) | (B extends U ? X : Y) | (C extends U ? X : Y)&lt;/b&gt; &lt;/span&gt;가 됩니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre class=&quot;excel&quot;&gt;&lt;code&gt;type MyExclude&amp;lt;T, U&amp;gt; = T extends U ? never : T;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>TypeScript/Type Challenges</category>
      <category>exclude</category>
      <category>TS</category>
      <category>Type Challenges</category>
      <category>Typescript</category>
      <author>후끈후끈</author>
      <guid isPermaLink="true">https://likelacoste.tistory.com/59</guid>
      <comments>https://likelacoste.tistory.com/59#entry59comment</comments>
      <pubDate>Sat, 26 Nov 2022 11:00:06 +0900</pubDate>
    </item>
    <item>
      <title>2장 의미 있는 이름</title>
      <link>https://likelacoste.tistory.com/58</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;소프트웨어에서 이름은 어디에서나 사용된다. 변수에도 이름을 붙이고, 함수에도 이름을 붙이고, 인수와 클래스, 패키지에도 이름을 붙인다. 소스 파일에도 이름을 붙이고, 소스 파일이 담긴 디렉터리에도 이름을 붙인다. 이처럼 많은 부분에서 이름을 사용하는데, 이때 이름을 잘 지으면 여러모로 편하다. 이번 장에서는 이름을 잘 지을 수 있는 간단한 규칙 몇 가지를 소개한다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;의도를 분명히 밝혀라&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;코드를 단순하게 작성한다고 좋은 코드라고 말할 수 없다. 단순하게 작성했더라도 코드 맥락이 코드 자체에 명시적으로 드러나지 않는다면, 해당 코드를 어떤 의도로 작성했는지 또는 하는 일이 무엇인지 이해하기란 쉽지 않을 것이다. 이때 코드의 의미를 부여할 수 있는 것이 바로 이름이다. 의도가 분명하게 드러나는 이름을 사용한 코드는 이해와 변경이 쉽다. 그러므로 이름을 주의 깊게 살펴 더 나은 이름으로 개선하는 것이 자신을 포함해 코드를 읽는 사람으로 하여금 편안함을 제공할 수 있다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;그릇된 정보를 피하라&lt;/span&gt;&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;프로그래머는 코드에 그릇된 단서를 남겨서는 안 된다.&amp;nbsp;이는 코드의 의미를 흐리게 된다. 나름대로 널리 쓰이는 의미가 있는 단어를 다른 의미로 사용해도 안된다. 예를 들어 직각 삼각형의 빗변(hypotenuse)을 구현할 때 hp가 훌륭한 약어로 보일지라도 hp라는 변수는 읽는 사람들로 하여금 잘못된 정보를 제공할 수 있다. 그리고 여러 계정을 그룹을 묶을 때, 실제 List가 아니라면, accountList라고 이름 짓지 않는 것이 좋다. 이는 계정을 담는 컨테이너가 실제 List가 아니라면 프로그래머에게 잘못된 정보를 제공할 수 있기 때문에 accountGroup, bunchOfAccounts, 아니면 단순히 Accounts라고 짓는 것이 좋다.&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;서로 비슷한 이름을 사용하지 않도록 주의해야 한다. 비슷한 이름을 사용하게 된다면 읽는 사람이 그 차이를 알기란 쉽지 않다. 그리고 유사한 개념은 유사한 표기법을 사용하는 것이 좋다. (이것도 하나의 정보가 될 수 있는데, 일관성이 떨어지는 표기법은 잘못된 정보를 전달할 수 있다.) 이름으로 잘못된 정보를 제공하는 예가 L과 O를 변수로 사용하는 것이다. 소문자 L은 숫자 1처럼 보이고, O는 숫자 0처럼 보이게 된다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;의미 있게 구분하라&lt;/span&gt;&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;연속된 숫자를 덧붙이거나 불용어(noise word)를 추가하는 방식은 적절하지 못하다. 이름이 달라야 한다면 의미도 달라져야 한다. 연속적인 숫자를 덧붙인 이름(a1, a2,... aN)은 의도적인 이름과는 정반대다. 이런 이름은 잘못된 정보를 제공하는 이름도 아니며, 아무런 정보를 제공하지 못하는 이름이다. (저자의 의도가 전혀 드러나지 않는다.)&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;불용어를 추가한 이름 역시 아무런 정보도 제공하지 못한다. Product라는 클래스가 있다고 가정해보자. 다른 클래스를 ProductInfo 또는 ProductData라고 부른다면 개념을 구분하지 않은 채 이름만 달리 한 경우다. (Info나 Data는 의미가 불분명한 불용어다.) 변수 이름에 variable이라는 단어를 붙이거나 표 이름에 table이라는 이름을 붙이는 것은 안된다. 읽는 사람이 차이를 알도록 이름을 지어야 한다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;발음하기 쉬운 이름을 사용하라&lt;/span&gt;&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;발음하기 쉬운 이름은 중요하다. 이는 프로그래밍은 사회활동이기 때문이다. 작성한 코드에 대해 회의를 하는 등의 커뮤니케이션이 이루어질 때, 발음이 어렵다면 방해가 될 수 있다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;검색하기 쉬운 이름을 사용하라&lt;/span&gt;&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;문자 하나를 사용하는 이름과 상수는 텍스트 코드에서 쉽게 눈에 띄지 않는다는 문제점이 있다. MAX_CLASSES_PER_STUDENT는 grep으로 찾기가 쉽지만, 알파벳 'e'는 찾기가 까다롭다. 'e'는 영어에서 가장 많이 쓰이는 문자이기 때문에 거의 모든 문장에서 등장하기 때문에 'e'를 grep 하면 거의 모든 단어가 검색되어 내가 원하는 부분을 찾기 어렵다. 이런 관점에서 긴 이름이 짧은 이름보다 좋고, 검색하기 쉬운 이름이 하나의 문자 또는 상수보다 좋다.&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;nix&quot;&gt;&lt;code&gt;let realDaysPerIdealDay = 4;
const WORK_DAYS_PER_WEEK = 5;
let sum = 0;
for(let i = 0; i &amp;lt; NUMBER_OF_TASKS; i++) {
  let realTaskDays = taskEstimate[i] * realDaysPerIdealDay;
  sum += realTaskDays;
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;위 코드에서 &lt;code&gt;sum&lt;/code&gt;이 별로 유용하지 않으나 최소한 검색이 가능하다. 그리고 &lt;code&gt;WORK_DAYS_PER_WEEK&lt;/code&gt;이라는 변수 이름의 길이는 길지만 찾기가 쉽고, 그 의미가 명확하기 때문에 코드를 이해하기 쉽다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;인코딩을 피하라&lt;/span&gt;&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;이름에 인코딩할 정보는 아주 많다. 유형이나 범위 정보까지 인코딩에 넣으면 그만큼 이름을 해독하기 어려워진다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;헝가리식 표기법&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;헝가리식 표기법은 프로그래밍 언어에서 변수 및 함수의 인자 이름 앞에 데이터 타입을 명시하는 코딩 규칙이다. 예를 들어 &lt;code&gt;byte&lt;/code&gt;나 &lt;code&gt;boolan&lt;/code&gt; 타입에는 &lt;code&gt;b&lt;/code&gt;를, &lt;code&gt;Array(배열)&lt;/code&gt; 타입은 &lt;code&gt;arr&lt;/code&gt;를, &lt;code&gt;String(문자열) 타입은&lt;/code&gt; &lt;code&gt;str&lt;/code&gt;을 붙여 타입을 명시한다. 과거에는 컴파일러가 타입을 점검하지 않았으므로 프로그래머에게 타입을 기억할 단서가 필요했기 때문에 변수 및 함수의 인자 앞에 데이터 타입을 명시하였다. 하지만 IDE가 발전함에 따라 코드를 컴파일하지 않고도 타입 오류를 감지할 정도로 발전했다. 따라서 이제는 헝가리식 표현법이나 기타 인코딩 방식이 변수나 함수, 클래스의 이름이나 타입을 바꾸기가 어려워지며, 가독성도 떨어뜨린다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;멤버 변수 접두어&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;이제는 멤버 변수에 &lt;code&gt;m_&lt;/code&gt;이라는 접두어를 붙일 필요가 없다. 클래스와 함수는 접두어가 필요 없을 정도로 작아야 한다. 접두어는 옛날에 작성한 구닥다리 코드가 되었다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;인터페이스 클래스와 구현 클래스&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;인터페이스 이름에 접두어를 붙이지 않는 편이 좋다. 인터페이스 클래스 이름과 구현 클래스 이름 중 하나를 인코딩해야 한다면 구현 클래스 이름이 훨씬 좋다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;자신의 기억령을 자랑하지 마라&lt;/span&gt;&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;코드를 읽으면서 변수 이름을 자신이 아는 이름으로 변환해야 한다면 그 변수 이름은 바람직하지 못하다. 똑똑한 프로그래머와 전문가 프로그래머 사이에서 나타나는 차이는 전문가 프로그래머는 명료함이 최고라는 사실을 이해한다는 점이다. 전문가 프로그래머는 자신의 능력을 좋은 방향으로 사용해 남들이 이해하는 코드를 내놓는다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;클래스 이름&lt;/span&gt;&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;클래스 이름과 객체 이름은 명사나 명사구가 적합하다. Customer, WikiPage, Account, AddressParser 등이 좋은 예이다. Manager, Processor, Data, Info 등과 같은 단어는 피하고, 동사는 사용하지 않는다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;메서드 이름&lt;/span&gt;&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;메서드 이름은 동사나 동사구가 적합하다. postPayment, deletePage, save 등이 좋은 예이다. 접근자, 변경자, 조건자에 따라 값 앞에 get, set, is를 붙인다. 그리고 생성자를 중복 정의할 때는 정적 팩도리 메서드를 사용한다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;기발한 이름은 피하라&lt;/span&gt;&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;재미난 이름보다는 명료한 이름을 선택해야 한다. 간혹 프로그래머가 나름대로 재치를 발휘해 이름을 작성하는 경우가 있는데, 특정 문화에서만 사용하는 농담은 피하는 편이 좋고, 의도를 분명하고 솔직하게 표현하는 것이 좋다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;한 개념에 한 단어를 사용하라&lt;/span&gt;&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;추상적인 개념 하나에 단어 하나를 선택해 이를 고수하는 것이 좋다. 메서드 이름은 독자적이고 일관적이어야 프로그래머로 하여금 주석을 뒤져보지 않고도 올바른 메서드를 선택할 수 있게 해 준다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;말장난을 하지 마라&lt;/span&gt;&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;한 단어를 두 가지 목적으로 사용하지 말아야 한다. 다른 개념에 같은 단어를 사용한다는 것은 말장난에 불과하다. 예를 들어 지금까지 구현한 add 메서드는 모두 기존 값 두 개를 더하거나 이어서 새로운 값을 만든다고 가정해보자. 집합에 값을 추가하는 메서드를 새로 작성한다고 해서 해당 메서드에 add를 사용하는 것은 기존에 작성한 add과는 맥락이 다르므로 일관성을 무너뜨리는 행위이다. add를 사용하기보다는 insert나 append로 이름을 짓는 것이 적당하다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;프로그래머는 코드를 최대한 이해하기 쉽게 짜야한다. 집중적인 탐구가 필요한 코드가 아니라 대충 훑어봐도 이해할 수 있는 코드를 작성하는 것을 목표로 해야 한다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;해법 영역에서 가져온 이름을 사용하라&lt;/span&gt;&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;코드를 읽을 사람도 프로그래머이기 때문에 전산 용어, 알고리즘 이름, 패턴 이름, 수학 용어 등을 사용해도 괜찮다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;문제 영역에서 가져온 이름을 사용하라&lt;/span&gt;&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;적절한 '프로그래머 용어'가 없다면 문제 영역에서 이름을 가져온다. 우수한 프로그래머와 설계자라면 해법 영역과 문제 영역을 구분할 줄 알아야 한다. 문제 영역 개념과 관련이 깊은 코드라면 문제 영역에서 이름을 가져와야 한다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;의미 있는 맥락을 추가하라&lt;/span&gt;&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;firstName, lastName, street, houseNumber, city, state, zipcode라는 변수가 있다고 해보자. 변수를 훑어보면 주소라는 사실을 금방 알 수 있다. 하지만 어느 메서드가 state라는 변수 하나만을 사용한다면? 변수 state이 주소의 일부분이라는 것을 알기는 쉽지 않을 것이다. 여기에 addr이라는 접두어를 추가해서 addFirstName, addrLastName, addrState라고 쓰면 맥락이 좀 더 분명해진다. (물론 Address라는 클래스를 생성하면 더 좋다.)&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;불필요한 맥락을 없애라&lt;/span&gt;&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;고급 휘발유 충전소(Gas Station Deluxe)라는 애플리케이션을 개발한다고 할 때, 모든 클래스 이름을 GSD로 시작하는 것은 바람직하지 못하다. 일반적으로 짧은 이름이 긴 이름보다 좋다. 단, 의미가 분명한 경우에 한해서다. 이름에 불필요한 맥락을 추가하지 않도록 주의해야 한다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;대다수의 사람들이 자신이 짠 클래스 이름과 메서드 이름을 모두 암기하지 못한다. 암기는 요즘 나오는 도구에게 맡기고, 우리는 문장이나 문단처럼 읽히는 코드 아니면 적어도 표나 자료 구조처럼 읽히는 코드를 짜는데 집중하는 것이 마땅하다.&lt;/span&gt;&lt;/p&gt;</description>
      <category>Books/Clean Code</category>
      <category>Clean Code</category>
      <category>깨끗한 코드</category>
      <category>독서</category>
      <category>책</category>
      <category>클린코드</category>
      <author>후끈후끈</author>
      <guid isPermaLink="true">https://likelacoste.tistory.com/58</guid>
      <comments>https://likelacoste.tistory.com/58#entry58comment</comments>
      <pubDate>Fri, 25 Nov 2022 15:23:41 +0900</pubDate>
    </item>
    <item>
      <title>[18] Length of Tuple</title>
      <link>https://likelacoste.tistory.com/57</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;color: #000000; background-color: #f6e199;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&amp;nbsp;문제&amp;nbsp;&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR'; color: #000000;&quot;&gt;배열(튜플)을 받아 길이를 반환하는 제네릭 &lt;code&gt;Length&amp;lt;T&amp;gt;&lt;/code&gt;를 구현하세요.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;color: #000000; background-color: #f6e199;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&amp;nbsp;예시&amp;nbsp;&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;pre class=&quot;rust&quot;&gt;&lt;code&gt;type tesla = ['tesla', 'model 3', 'model X', 'model Y']
type spaceX = ['FALCON 9', 'FALCON HEAVY', 'DRAGON', 'STARSHIP', 'HUMAN SPACEFLIGHT']

type teslaLength = Length&amp;lt;tesla&amp;gt;  // expected 4
type spaceXLength = Length&amp;lt;spaceX&amp;gt; // expected 5&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;  &lt;b&gt;도전하기&lt;/b&gt;&lt;b&gt;&lt;/b&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1668836227554&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;TS Playground - An online editor for exploring TypeScript and JavaScript&quot; data-og-description=&quot;The Playground lets you write TypeScript or JavaScript online in a safe and sharable way.&quot; data-og-host=&quot;www.typescriptlang.org&quot; data-og-source-url=&quot;https://www.typescriptlang.org/play?#code/PQKgUABBCMAcEFoIBkCmA7A5gFwBYQHsAzCAFQFcAHAG1UkQUafoCMBPCAZwEt0CD0EABQABHnwEBKCAGJANkOABsdnYqtevRmaIgCcnAHN3qogBh7AL6NDAOUuAYVcmARcYiBsHsAioxEAcdYBdxwD6dEQBg9gDTXAGquAKU0QgDgTgCSNgLWdEAAGaFh4ADykAHxRnoA2tYAga36AHIOAKWMAdAYQgBBjgDtDAFxFUdXYnPTYbJSoENionNQAhhAAvBAA2gDkre0dAwA0EAMAtgQAJqjUEADM45Mz84sAGqvTcwsQAJoDALr1jc2clB0AxqibPf0DAGIAgsgAwgDyAHIQAJw7V4fH4QAASAFEXgA1I4TAYAEQASi8AOI-HYAZVIL0RGNBAEkAAo7UEAVQAsi9fhjCS93uCnsh8SjQaQTkUGk0Wm1OrEcPhenyEsNOkkoMBgBBUAAPJrXVqzCAAFjOXMuNzuQoFKAw-Pi6tumzFEqlstQ8tQioArPRqlEimKUdxsKDyCxAAujgBxBiCAF57AAx15QguGw2EonHKEtq11w+QAVpx8gQAE6YYBwYAAawIYBAwDA+dAEAA+iXS2XSxBADejfvdEEAKvOAHZaIIBQ8cApB3F8udosQXP5znNLWJMW9DroNj5sCFrudiCAGUXACVDgA6liCAAHnXPOO9OK73uFNKMnsC1zhAAN4QcEAR3IHWoE3BZvlEAAvhAiEmCFNJiJ+whozfaFgbTAOQ2DcNQnADPm1wCJwh4il0vSDPBOzrPsKxwqhWwoXsixHMcEAdJwEDQegsFgCRsFcFchoPIMQJfL8AJwvRIIQtCsKTEiqLonCWI4niRIkhSVIQDSdIMkyLJsvhhHETB2B9se1yEW0tH0PecrYPEl7XtQ8SDv2xDciMSQTEqSSmepD5aTpN76bqwrnEZBp3KZEBWhZYz0Ca36cAgMqaf5Sbvkm9CDh5XnipKvn+dZQUhWFDm4PEAy4As1AEBAADuybULMAyWacE5TluFaACdNgAy4xAgAXTYAIzWbqVPZ5qA9BioAqBOAK9NECAK81gAE434AZBiGYYRsAUYxvGiYpmmsDAKOnBZagSaZtmUDtV1-qBsGobhpGnDRnGCbJqm6acAQ1AgdwMGtRAZWAB6dEC6MEgAnLVtw27WN+0TUd01ZjmeZgEAA&quot; data-og-url=&quot;https://www.typescriptlang.org/play/?&quot; data-og-image=&quot;&quot;&gt;&lt;a href=&quot;https://www.typescriptlang.org/play?#code/PQKgUABBCMAcEFoIBkCmA7A5gFwBYQHsAzCAFQFcAHAG1UkQUafoCMBPCAZwEt0CD0EABQABHnwEBKCAGJANkOABsdnYqtevRmaIgCcnAHN3qogBh7AL6NDAOUuAYVcmARcYiBsHsAioxEAcdYBdxwD6dEQBg9gDTXAGquAKU0QgDgTgCSNgLWdEAAGaFh4ADykAHxRnoA2tYAga36AHIOAKWMAdAYQgBBjgDtDAFxFUdXYnPTYbJSoENionNQAhhAAvBAA2gDkre0dAwA0EAMAtgQAJqjUEADM45Mz84sAGqvTcwsQAJoDALr1jc2clB0AxqibPf0DAGIAgsgAwgDyAHIQAJw7V4fH4QAASAFEXgA1I4TAYAEQASi8AOI-HYAZVIL0RGNBAEkAAo7UEAVQAsi9fhjCS93uCnsh8SjQaQTkUGk0Wm1OrEcPhenyEsNOkkoMBgBBUAAPJrXVqzCAAFjOXMuNzuQoFKAw-Pi6tumzFEqlstQ8tQioArPRqlEimKUdxsKDyCxAAujgBxBiCAF57AAx15QguGw2EonHKEtq11w+QAVpx8gQAE6YYBwYAAawIYBAwDA+dAEAA+iXS2XSxBADejfvdEEAKvOAHZaIIBQ8cApB3F8udosQXP5znNLWJMW9DroNj5sCFrudiCAGUXACVDgA6liCAAHnXPOO9OK73uFNKMnsC1zhAAN4QcEAR3IHWoE3BZvlEAAvhAiEmCFNJiJ+whozfaFgbTAOQ2DcNQnADPm1wCJwh4il0vSDPBOzrPsKxwqhWwoXsixHMcEAdJwEDQegsFgCRsFcFchoPIMQJfL8AJwvRIIQtCsKTEiqLonCWI4niRIkhSVIQDSdIMkyLJsvhhHETB2B9se1yEW0tH0PecrYPEl7XtQ8SDv2xDciMSQTEqSSmepD5aTpN76bqwrnEZBp3KZEBWhZYz0Ca36cAgMqaf5Sbvkm9CDh5XnipKvn+dZQUhWFDm4PEAy4As1AEBAADuybULMAyWacE5TluFaACdNgAy4xAgAXTYAIzWbqVPZ5qA9BioAqBOAK9NECAK81gAE434AZBiGYYRsAUYxvGiYpmmsDAKOnBZagSaZtmUDtV1-qBsGobhpGnDRnGCbJqm6acAQ1AgdwMGtRAZWAB6dEC6MEgAnLVtw27WN+0TUd01ZjmeZgEAA&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://www.typescriptlang.org/play?#code/PQKgUABBCMAcEFoIBkCmA7A5gFwBYQHsAzCAFQFcAHAG1UkQUafoCMBPCAZwEt0CD0EABQABHnwEBKCAGJANkOABsdnYqtevRmaIgCcnAHN3qogBh7AL6NDAOUuAYVcmARcYiBsHsAioxEAcdYBdxwD6dEQBg9gDTXAGquAKU0QgDgTgCSNgLWdEAAGaFh4ADykAHxRnoA2tYAga36AHIOAKWMAdAYQgBBjgDtDAFxFUdXYnPTYbJSoENionNQAhhAAvBAA2gDkre0dAwA0EAMAtgQAJqjUEADM45Mz84sAGqvTcwsQAJoDALr1jc2clB0AxqibPf0DAGIAgsgAwgDyAHIQAJw7V4fH4QAASAFEXgA1I4TAYAEQASi8AOI-HYAZVIL0RGNBAEkAAo7UEAVQAsi9fhjCS93uCnsh8SjQaQTkUGk0Wm1OrEcPhenyEsNOkkoMBgBBUAAPJrXVqzCAAFjOXMuNzuQoFKAw-Pi6tumzFEqlstQ8tQioArPRqlEimKUdxsKDyCxAAujgBxBiCAF57AAx15QguGw2EonHKEtq11w+QAVpx8gQAE6YYBwYAAawIYBAwDA+dAEAA+iXS2XSxBADejfvdEEAKvOAHZaIIBQ8cApB3F8udosQXP5znNLWJMW9DroNj5sCFrudiCAGUXACVDgA6liCAAHnXPOO9OK73uFNKMnsC1zhAAN4QcEAR3IHWoE3BZvlEAAvhAiEmCFNJiJ+whozfaFgbTAOQ2DcNQnADPm1wCJwh4il0vSDPBOzrPsKxwqhWwoXsixHMcEAdJwEDQegsFgCRsFcFchoPIMQJfL8AJwvRIIQtCsKTEiqLonCWI4niRIkhSVIQDSdIMkyLJsvhhHETB2B9se1yEW0tH0PecrYPEl7XtQ8SDv2xDciMSQTEqSSmepD5aTpN76bqwrnEZBp3KZEBWhZYz0Ca36cAgMqaf5Sbvkm9CDh5XnipKvn+dZQUhWFDm4PEAy4As1AEBAADuybULMAyWacE5TluFaACdNgAy4xAgAXTYAIzWbqVPZ5qA9BioAqBOAK9NECAK81gAE434AZBiGYYRsAUYxvGiYpmmsDAKOnBZagSaZtmUDtV1-qBsGobhpGnDRnGCbJqm6acAQ1AgdwMGtRAZWAB6dEC6MEgAnLVtw27WN+0TUd01ZjmeZgEAA&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url();&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;TS Playground - An online editor for exploring TypeScript and JavaScript&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;The Playground lets you write TypeScript or JavaScript online in a safe and sharable way.&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;www.typescriptlang.org&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&amp;nbsp;&lt;/h2&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;color: #000000; background-color: #f6e199;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&amp;nbsp;풀이&amp;nbsp;&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;span style=&quot;color: #000000; background-color: #f6e199;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR'; color: #000000;&quot;&gt;JavaScript에서 배열의 길이를 &lt;code&gt;length&lt;/code&gt;프로퍼티를 사용하여 구할 수 있는 것처럼, 타입 안에서도 똑같이 사용할 수 있다. 이때 JavaScript에서와 같이 &lt;code&gt;T.length&lt;/code&gt;의 형태로 사용하지 않고 &lt;code&gt;T['length']&lt;/code&gt;와 같은 형태로 배열의 길이 속성을 꺼내 쓸 수 있다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre class=&quot;scala&quot;&gt;&lt;code&gt;type Length&amp;lt;T extends { length: number }&amp;gt; = T[&quot;length&quot;];&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR'; color: #000000;&quot;&gt;&lt;code&gt;&amp;lt;T extends { length: number }&amp;gt;&lt;/code&gt;라고 작성한 이유는 입력으로 주어진 타입변수가 해당 프로퍼티를 가지고 있음을 알려줘야 하기 때문이다.&lt;/span&gt;&lt;/p&gt;</description>
      <category>TypeScript/Type Challenges</category>
      <category>Length of Tuple</category>
      <category>TS</category>
      <category>Type Challenges</category>
      <category>Typescript</category>
      <author>후끈후끈</author>
      <guid isPermaLink="true">https://likelacoste.tistory.com/57</guid>
      <comments>https://likelacoste.tistory.com/57#entry57comment</comments>
      <pubDate>Sat, 19 Nov 2022 14:39:04 +0900</pubDate>
    </item>
    <item>
      <title>1장 깨끗한 코드</title>
      <link>https://likelacoste.tistory.com/56</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;프로그래밍이란 기계가 실행할 정도로 &lt;b&gt;상세하게&lt;/b&gt; 요구사항을 명시하는 작업을 말한다. 요구사항을 명시하기 위해서 필요한 것이 바로 '코드'이다. 코드란, 요구사항을 상세히 표현하는 언어 또는 수단을 말한다. 우리가 어떤 언어로든지 코드를 작성하게 된다면, 기계가 이해하고 실행할 수 있을 정도로 엄밀하고 정확하고 상세하고 정형화 되도록 작성해야 한다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;우리는 코드를 작성할 때, 좋은 코드 혹은 깨끗한 코드를 작성해야 한다는 것은 알고 있다. 하지만 좋은 코드, 깨끗한 코드를 작성하기 위해서는 시간과 노력이 필요하다. 우리는 왜 좋은 코드를 작성해야 하는 것일까?&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;어느날 새로운 회사로 취업해 출근을 했다고 생각해보자. 출근을 하자마자 내가 맡게된 파트의 작성된 코드를 보니, 변수 명은 아무 의미가 없이 작성되어 있고, 하나의 함수가 여러 기능을 담당하고 있어 함수의 길이가 엄청 길어져 있고,&amp;nbsp; 여기저기 반복되어 코드가 작성되어 있다면, 당신은 어떤 생각이 들겠는가? 아마 코드를 작성한 사람을 욕하며 코드를 새로 작성하고 싶다는 생각을 할 것이다.&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;코드를 작성할 때, 깨끗한 코드를 작성하려면 개발 속도가 나지 않아 효율적이지 못하다고 생각할 수도 있다. 하지만 나쁜 코드가 쌓이면 쌓일 수록 엉망진창인 상태로 인해 개발 속도와 팀 생산성은 크게 떨어지게 된다. 빨리 가는 방법은 언제나 코드를 최대한 깨끗하게 유지하는 것이다.&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;그렇다면 깨끗한 코드란 무엇일까? 유명한 프로그래머의 의견을 들어보자.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;비야네 스트롭스트룹(C++ 창시자)&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;color: #000000;&quot;&gt;우아한 코드를 좋아한다. 논리가 간단해야 버그가 숨어들지 못한다. 의존성을 최대한 줄여양 유지보수가 쉬워진다. 오류는 명백한 전략에 의거해 철저히 처리한다. 성능을 최적으로 유지해야 사람들이 원칙 없는 최적화로 코드를 망치려는 유혹에 빠져들지 않는다. 깨끗한 코드는 한 가지를 제대로 한다.&lt;/span&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;rarr;&amp;nbsp;보기에 즐거운 코드&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;rarr;&amp;nbsp;효율 적인 코드&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;rarr;&amp;nbsp;세세한 사항까지 꼼꼼하게 처리하는 코드 - 철저한 오류 처리&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;rarr;&amp;nbsp;한가지에 집중한 코드 - 목적과 의도가 분명&lt;/span&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;그래디 부치&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;color: #000000;&quot;&gt;깨끗한 코드는 단순하고 직접적이다. 깨끗한 코드는 잘 쓴 문장처럼 읽힌다. 깨끗한 코드는 결코 설계자의 의도를 숨기지 않는다. 오히려 명쾌한 추상화와 단순한 제어문으로 가득하다.&lt;/span&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;rarr;&amp;nbsp;가독성이 좋아야 한다. - 필요한 내용만 담기&lt;/span&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;콘 데이브 토미스&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;color: #000000;&quot;&gt;깨끗한 코드는 작성자가 아닌 사람도 읽기 쉽고 고치기 쉽다. 단위 테스트 케이스와 인수 테스트 케이스가 존재한다. 깨끗한 코드에는 의미 있는 이름이 붙는다. 특정 목적을 달성하는 방법은 하나만 제공한다. 의존성은 최소이며 각 의존성을 명확히 정의한다. API는 명확하며 최소로 줄였다. 언어에 따라 필요한 모든 정보를 코드만으로 명확히 표현할 수 없기에 문학적으로 표현해야 마땅하다.&lt;/span&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;rarr;&amp;nbsp;다른 사람이 고치기 쉬운 코드&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;rarr;&amp;nbsp;테스트 케이스 - 작은 단위&lt;/span&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;마이클 페더스&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;color: #000000;&quot;&gt;깨끗한 코드의 특징은 많지만 그 주에서도 모두를 아우르는 특징이 하나 있다. 깨끗한 코드는 언제나 누군가 주의 깊게 짰다는 느낌을 준다. 고치려고 살펴봐도 딱히 손 댈 곳이 없다. 작성자가 이미 모든 사황을 고려했으므로 고칠 궁리를 하다보면 언제나 제자리로 돌아온다. 그리고는 누군가 남겨준 코드, 누군가 주의 깊게 짜놓은 작품에 감사를 느낀다.&lt;/span&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;rarr; 주의 깊게 작성한 코드 - 깔끔하고 세세한 사항까지 꼼꼼하게 신경쓴 코드&lt;/span&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;론 제프리스&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;코드 규칙&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;&lt;span style=&quot;color: #000000;&quot;&gt;1.&amp;nbsp; 모든 테스트를 통과한다.&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #000000;&quot;&gt;2. 중복이 없다.&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #000000;&quot;&gt;3. 시스템 내 모든 설계 아이디어를 표현한다.&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;color: #000000;&quot;&gt;4. 클래스, 메서드, 함수 등을 최대한 줄인다.&lt;/span&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;rarr;&amp;nbsp;중복을 줄여라&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;rarr;&amp;nbsp;한 기능만 수행하라&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;rarr;&amp;nbsp;제대로 표현하라&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;rarr;&amp;nbsp;작게 추상화하라&lt;/span&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;워드 커닝햄&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;color: #000000;&quot;&gt;코드를 읽으면서 짐작했던 기능을 각 루틴이 그대로 수행한다면 깨끗한 코드라 불러도 되겠다. 코드가 그 문제를 풀기 위한 언어처럼 보인다면 아름다운 코드라 불러도 되겠다.&lt;/span&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;rarr;&amp;nbsp;읽으면서 짐작한대로 돌아가는 코드&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;rarr;&amp;nbsp;단순하고 명료한 코드&lt;/span&gt;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;잘 짠 코드가 전부가 아니다. 시간이 지나도 언제나 깨끗하게 유지해야하는 것이 중요하다. 깨끗한 코드를 작성하기 위해 한꺼번에 많은 시간과 노력을 투자해 코드를 정리할 필요는 없다. 변수의 이름 하나를 개선하고, 조금 긴 함수 하나를 분할하고, 약간의 중복을 제거하고, 복잡한 if문 하나를 정리하면 충분하다.&lt;/span&gt;&lt;/p&gt;</description>
      <category>Books/Clean Code</category>
      <category>Clean Code</category>
      <category>깨끗한 코드</category>
      <category>독서</category>
      <category>책</category>
      <category>클린코드</category>
      <author>후끈후끈</author>
      <guid isPermaLink="true">https://likelacoste.tistory.com/56</guid>
      <comments>https://likelacoste.tistory.com/56#entry56comment</comments>
      <pubDate>Wed, 16 Nov 2022 14:41:58 +0900</pubDate>
    </item>
    <item>
      <title>[14] easy first</title>
      <link>https://likelacoste.tistory.com/55</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;background-color: #f6e199;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #000000; font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&amp;nbsp;문제&amp;nbsp;&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000; font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;배열(듀플) T를 받아 첫 원소의 타입을 반환하는 제네릭 First를 구현하세요.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;background-color: #f6e199;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #000000; font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&amp;nbsp;예시&amp;nbsp;&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;pre class=&quot;fsharp&quot;&gt;&lt;code&gt;type arr1 = ['a', 'b', 'c']
type arr2 = [3, 2, 1]

type head1 = First&amp;lt;arr1&amp;gt; // expected to be 'a'
type head2 = First&amp;lt;arr2&amp;gt; // expected to be 3&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000; font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;  도전하기&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1668566663881&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;TS Playground - An online editor for exploring TypeScript and JavaScript&quot; data-og-description=&quot;The Playground lets you write TypeScript or JavaScript online in a safe and sharable way.&quot; data-og-host=&quot;www.typescriptlang.org&quot; data-og-source-url=&quot;https://www.typescriptlang.org/play?#code/PQKgUABBCMAsEFoIDECWAnAzgFwgewDMIBBddAQwE9JEE76aAjSkgO2wAs9WXkBXCAAoAAuXYE+ASggBiQDZDgAbHZ5MlRo0ZmiIAnJwBzd6qIAYewC+jgwDlLgGFXpAAwAq1wD6dEQNg9gEVGIgapmIgBbHAMYOANcYhAAYXAUPHAEXGIQAwewA01wA1VwBSmiEAcCcASRsBazohrNCxsAB5bAD5HCEAbWsAQNdjADkHAFLGAOgMIQAgxwB2hgC4G607sTBpsSgAHAFMIFXRoCABeCABtAHJyWYAaCFnGJZWAY1mAXV6B4dGAJkmZgGZlw+XoXag9oYgOQfIAE3Gp7Jxc0egCiGBgCCDAAeQw22EGzwg2DwEEYw3mszuw0eL2O7wwnyOv3+gJBgzBEKhMLhEFONE61gavwA4qhsAAJPiMQALo4AcQYggBeewAMda0HthsP1MK1-t0NhxagArTC1PDoADmwDgwAA1ngwCBgGAtaAIAB9fUGw0GiCAG9GucyIIAVecAOy0QEKAUg69UbnbqIBqtX17h88rZceDWM9MCMeNNtr8pmJqNqQE6XYaIIAZRcAJUOADqWIIAAecALuNJ2Nx-VuzWoAC2-VluE9wwA3hAAKIARz45AANssa3iwRAAL4QAjoPBFlbCCsIMXNpuDVhywaYYB8bCoJuYRFgCsQDbkTDTk7TGht0F5euNpu5b25abnCCXGBh5anAoFRa79sHhvNk8YvLTQTSCa-aCHC9q3IXkcHQVBJy7G8hB-P8APvR8oD3fEXyPd8cjPKDWEGAA3QZ0Hgp991yQ831PaY+ADQYCHAiEoIo54qJo54CN2Fd9kBMhZSDKYdygHEh0wBBgX3ITOPQGhT1mVg8GwUgKEoWYHxofjuiE59RL7cSoFPasAAZeXmVRKAAGVQZVBlmLslNY6NczzCBABOmwAZcYgQALpsAEZq7LjAswFAGhfkAVAnAFemiBAFeawACcdiHk+QFIURUwMVJWlWUFSVMRMAAdzwlU1SgQKQu5XkOH5QVhWAUVxSlGV5UVWBgEwPAmznVBuB6PLHMAD06IF0JJABOWoqSri8qEsq5KatVdVNTAIA&quot; data-og-url=&quot;https://www.typescriptlang.org/play/?&quot; data-og-image=&quot;&quot;&gt;&lt;a href=&quot;https://www.typescriptlang.org/play?#code/PQKgUABBCMAsEFoIDECWAnAzgFwgewDMIBBddAQwE9JEE76aAjSkgO2wAs9WXkBXCAAoAAuXYE+ASggBiQDZDgAbHZ5MlRo0ZmiIAnJwBzd6qIAYewC+jgwDlLgGFXpAAwAq1wD6dEQNg9gEVGIgapmIgBbHAMYOANcYhAAYXAUPHAEXGIQAwewA01wA1VwBSmiEAcCcASRsBazohrNCxsAB5bAD5HCEAbWsAQNdjADkHAFLGAOgMIQAgxwB2hgC4G607sTBpsSgAHAFMIFXRoCABeCABtAHJyWYAaCFnGJZWAY1mAXV6B4dGAJkmZgGZlw+XoXag9oYgOQfIAE3Gp7Jxc0egCiGBgCCDAAeQw22EGzwg2DwEEYw3mszuw0eL2O7wwnyOv3+gJBgzBEKhMLhEFONE61gavwA4qhsAAJPiMQALo4AcQYggBeewAMda0HthsP1MK1-t0NhxagArTC1PDoADmwDgwAA1ngwCBgGAtaAIAB9fUGw0GiCAG9GucyIIAVecAOy0QEKAUg69UbnbqIBqtX17h88rZceDWM9MCMeNNtr8pmJqNqQE6XYaIIAZRcAJUOADqWIIAAecALuNJ2Nx-VuzWoAC2-VluE9wwA3hAAKIARz45AANssa3iwRAAL4QAjoPBFlbCCsIMXNpuDVhywaYYB8bCoJuYRFgCsQDbkTDTk7TGht0F5euNpu5b25abnCCXGBh5anAoFRa79sHhvNk8YvLTQTSCa-aCHC9q3IXkcHQVBJy7G8hB-P8APvR8oD3fEXyPd8cjPKDWEGAA3QZ0Hgp991yQ831PaY+ADQYCHAiEoIo54qJo54CN2Fd9kBMhZSDKYdygHEh0wBBgX3ITOPQGhT1mVg8GwUgKEoWYHxofjuiE59RL7cSoFPasAAZeXmVRKAAGVQZVBlmLslNY6NczzCBABOmwAZcYgQALpsAEZq7LjAswFAGhfkAVAnAFemiBAFeawACcdiHk+QFIURUwMVJWlWUFSVMRMAAdzwlU1SgQKQu5XkOH5QVhWAUVxSlGV5UVWBgEwPAmznVBuB6PLHMAD06IF0JJABOWoqSri8qEsq5KatVdVNTAIA&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://www.typescriptlang.org/play?#code/PQKgUABBCMAsEFoIDECWAnAzgFwgewDMIBBddAQwE9JEE76aAjSkgO2wAs9WXkBXCAAoAAuXYE+ASggBiQDZDgAbHZ5MlRo0ZmiIAnJwBzd6qIAYewC+jgwDlLgGFXpAAwAq1wD6dEQNg9gEVGIgapmIgBbHAMYOANcYhAAYXAUPHAEXGIQAwewA01wA1VwBSmiEAcCcASRsBazohrNCxsAB5bAD5HCEAbWsAQNdjADkHAFLGAOgMIQAgxwB2hgC4G607sTBpsSgAHAFMIFXRoCABeCABtAHJyWYAaCFnGJZWAY1mAXV6B4dGAJkmZgGZlw+XoXag9oYgOQfIAE3Gp7Jxc0egCiGBgCCDAAeQw22EGzwg2DwEEYw3mszuw0eL2O7wwnyOv3+gJBgzBEKhMLhEFONE61gavwA4qhsAAJPiMQALo4AcQYggBeewAMda0HthsP1MK1-t0NhxagArTC1PDoADmwDgwAA1ngwCBgGAtaAIAB9fUGw0GiCAG9GucyIIAVecAOy0QEKAUg69UbnbqIBqtX17h88rZceDWM9MCMeNNtr8pmJqNqQE6XYaIIAZRcAJUOADqWIIAAecALuNJ2Nx-VuzWoAC2-VluE9wwA3hAAKIARz45AANssa3iwRAAL4QAjoPBFlbCCsIMXNpuDVhywaYYB8bCoJuYRFgCsQDbkTDTk7TGht0F5euNpu5b25abnCCXGBh5anAoFRa79sHhvNk8YvLTQTSCa-aCHC9q3IXkcHQVBJy7G8hB-P8APvR8oD3fEXyPd8cjPKDWEGAA3QZ0Hgp991yQ831PaY+ADQYCHAiEoIo54qJo54CN2Fd9kBMhZSDKYdygHEh0wBBgX3ITOPQGhT1mVg8GwUgKEoWYHxofjuiE59RL7cSoFPasAAZeXmVRKAAGVQZVBlmLslNY6NczzCBABOmwAZcYgQALpsAEZq7LjAswFAGhfkAVAnAFemiBAFeawACcdiHk+QFIURUwMVJWlWUFSVMRMAAdzwlU1SgQKQu5XkOH5QVhWAUVxSlGV5UVWBgEwPAmznVBuB6PLHMAD06IF0JJABOWoqSri8qEsq5KatVdVNTAIA&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url();&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;TS Playground - An online editor for exploring TypeScript and JavaScript&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;The Playground lets you write TypeScript or JavaScript online in a safe and sharable way.&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;www.typescriptlang.org&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;background-color: #f6e199;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #000000; font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&amp;nbsp;풀이&amp;nbsp;&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000; font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;해당 문제는 &lt;b&gt;인덱스 접근 연산자&lt;/b&gt;를 사용해서 풀 수 있습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000; font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;하지만 여기서 주의해야 할 점은 빈 배열이 들어 왔을 경우, 해당 배열에는 아무 원소도 존재하지 않기 때문에 인덱스 접근 연산자(T[0])는 우리가 원하는 대로 정확하게 동작하지 않습니다.&amp;nbsp;&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;routeros&quot;&gt;&lt;code&gt;type arr1 = ['a', 'b', 'c']
type arr2 = [3, 2, 1]
type arr3 = []

type First&amp;lt;T extends any[]&amp;gt; = T[0];


type head1 = First&amp;lt;arr1&amp;gt; 
type head2 = First&amp;lt;arr2&amp;gt; 
type head3 = First&amp;lt;arr3&amp;gt;

const newArr1:head1 = 'a';
const newArr2:head2 = 3;
const newArr3:head3 = undefined;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000; font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;그렇기 때문에 배열의 첫번째 원소에 접근하기 전에,&amp;nbsp; 해당 배열이 빈 배열인지 먼저 확인해야 합니다. 이때 &lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;조건부 타입&lt;/b&gt;을 사용하면 타입을 보다 명확하게 지정할 수 있습니다.&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;scala&quot;&gt;&lt;code&gt;type First&amp;lt;T extends any[]&amp;gt; = T extends []? never : T[0];&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>TypeScript/Type Challenges</category>
      <category>easy first</category>
      <category>TS</category>
      <category>Type Challenges</category>
      <category>Typescript</category>
      <author>후끈후끈</author>
      <guid isPermaLink="true">https://likelacoste.tistory.com/55</guid>
      <comments>https://likelacoste.tistory.com/55#entry55comment</comments>
      <pubDate>Wed, 16 Nov 2022 11:52:07 +0900</pubDate>
    </item>
    <item>
      <title>Mapped Types</title>
      <link>https://likelacoste.tistory.com/54</link>
      <description>&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;중복을 피하기위해 기존에 정의되어 있는 타입을 새로운 타입으로 변환해 주는 문법(자바스크립트의 &lt;code&gt;map()&lt;/code&gt;함수를 적용한 것과 같은 효과)&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre class=&quot;dts&quot;&gt;&lt;code&gt;// 기존 타입
{
  name: string;
  email: string;
}

// 새로운 타입
{
  name: number;
  email: number;
}&lt;/code&gt;&lt;/pre&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&amp;nbsp;&lt;/h2&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;  문법&lt;/span&gt;&lt;/b&gt;&lt;/h2&gt;
&lt;pre class=&quot;ada&quot;&gt;&lt;code&gt;type Name = 'Kim' | 'Park' | 'Shin';&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;위와 같이 김, 박, 신을 유니온 타입으로 묶어주는 &lt;code&gt;Name&lt;/code&gt;이라는 타입이 있습니다. 여기서 각 이름에 몸무게까지 붙인 객체를 만들고 싶다면 아래와 같이 변환할 수 있습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre class=&quot;yaml&quot;&gt;&lt;code&gt;type PersonProfiles = { [T in Name] : number};

const personInfo1: PersonProfiles = {
  Kim: 55,
  Park: 81,
  Shin: 77,
}

const personInfo2: PersonProfiles = {
  Kim: 64,
  Park: 61,
  Shin: 'no', // error: Type 'string' is not assignable to type 'number'.
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;code&gt;[T in Name]&lt;/code&gt; 부분은 앞에서 정의한 &lt;code&gt;Name&lt;/code&gt; 타입의 3개의 문자열을 각각 순회하여 &lt;code&gt;number&lt;/code&gt; 타입을 값으로 가지는 객체의 키로 정의가 됩니다. 이는 아래와 같이 정의하는 것과 동일합니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre class=&quot;elm&quot;&gt;&lt;code&gt;type PersonProfiles = {
  Kim: number;
  Park: number;
  Shin: number;
}&lt;/code&gt;&lt;/pre&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&amp;nbsp;&lt;/h2&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;  예제&lt;/span&gt;&lt;/b&gt;&lt;/h2&gt;
&lt;pre class=&quot;groovy&quot;&gt;&lt;code&gt;type Subset&amp;lt;T&amp;gt; = {
  [K in keyof T]? : T[K];
}

interface Person{
  name: string;
  age: number;
}

const onlyName: Subset&amp;lt;Person&amp;gt; = {name: 'Kim'};
const onlyAge: Subset&amp;lt;Person&amp;gt; = {age: 12};
const personInfo: Subset&amp;lt;Person&amp;gt; = {name: 'Park', age:22};
const empty: Subset&amp;lt;Person&amp;gt; = {};&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre class=&quot;typescript&quot;&gt;&lt;code&gt;interface UserProfile {
  email: string;
  username: string;
  profilePhotoUrl: string;
}

// 1
interface UserProfileUpdate{
  email? : string;
  username? : string;
  profilePhotoUrl? : string;
}

// 2
type UserProfileUpdate = {
  email? : UserProfile['email'];
  username? : UserProfile['username'];
  profilePhotoUrl? : UserProfile['profilePhotoUrl'];
}

// 3 
type UserProfileUpdate = {
  [p in 'email' | 'username' | 'profilePhotoUrl']?: UserProfile[p]
}

// 4 
type UserProfileUpdate = {
  [p in keyof UserProfile]?: UserProfile[p]
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;참조&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;a href=&quot;https://www.typescriptlang.org/ko/docs/handbook/2/mapped-types.html&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://www.typescriptlang.org/ko/docs/handbook/2/mapped-types.html&lt;/a&gt;&lt;/b&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1667969196520&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;Documentation - Mapped Types&quot; data-og-description=&quot;이미 존재하는 타입을 재사용해서 타입을 생성하기&quot; data-og-host=&quot;www.typescriptlang.org&quot; data-og-source-url=&quot;https://www.typescriptlang.org/ko/docs/handbook/2/mapped-types.html&quot; data-og-url=&quot;https://www.typescriptlang.org/ko/docs/handbook/2/mapped-types.html&quot; data-og-image=&quot;&quot;&gt;&lt;a href=&quot;https://www.typescriptlang.org/ko/docs/handbook/2/mapped-types.html&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://www.typescriptlang.org/ko/docs/handbook/2/mapped-types.html&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url();&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;Documentation - Mapped Types&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;이미 존재하는 타입을 재사용해서 타입을 생성하기&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;www.typescriptlang.org&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://joshua1988.github.io/ts/usage/mapped-type.html&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://joshua1988.github.io/ts/usage/mapped-type.html&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1667969334739&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;맵드 타입 | 타입스크립트 핸드북&quot; data-og-description=&quot;맵드 타입(Mapped Type)이란? 맵드 타입이란 기존에 정의되어 있는 타입을 새로운 타입으로 변환해 주는 문법을 의미합니다. 마치 자바스크립트 map() API 함수를 타입에 적용한 것과 같은 효과를 가&quot; data-og-host=&quot;joshua1988.github.io&quot; data-og-source-url=&quot;https://joshua1988.github.io/ts/usage/mapped-type.html&quot; data-og-url=&quot;https://joshua1988.github.io/ts/usage/mapped-type.html&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/XZv4z/hyQvemPZk7/PMeTicZH3zbLxXhYcpkoJ1/img.png?width=758&amp;amp;height=324&amp;amp;face=0_0_758_324&quot;&gt;&lt;a href=&quot;https://joshua1988.github.io/ts/usage/mapped-type.html&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://joshua1988.github.io/ts/usage/mapped-type.html&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/XZv4z/hyQvemPZk7/PMeTicZH3zbLxXhYcpkoJ1/img.png?width=758&amp;amp;height=324&amp;amp;face=0_0_758_324');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;맵드 타입 | 타입스크립트 핸드북&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;맵드 타입(Mapped Type)이란? 맵드 타입이란 기존에 정의되어 있는 타입을 새로운 타입으로 변환해 주는 문법을 의미합니다. 마치 자바스크립트 map() API 함수를 타입에 적용한 것과 같은 효과를 가&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;joshua1988.github.io&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>TypeScript/TS</category>
      <category>Mapped type</category>
      <category>TS</category>
      <category>Typescript</category>
      <category>타입스크립트</category>
      <author>후끈후끈</author>
      <guid isPermaLink="true">https://likelacoste.tistory.com/54</guid>
      <comments>https://likelacoste.tistory.com/54#entry54comment</comments>
      <pubDate>Wed, 9 Nov 2022 12:00:04 +0900</pubDate>
    </item>
    <item>
      <title>[11] Tuple to Object</title>
      <link>https://likelacoste.tistory.com/53</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;background-color: #f6e199; font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;&amp;nbsp;문제&amp;nbsp;&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;배열(튜플)을 받아, 각 원소의 값을 key/value로 갖는 오브젝트 타입을 반환하는 타입을 구현하세요.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;background-color: #f6e199; font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;&amp;nbsp;예시&amp;nbsp;&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;pre class=&quot;vim&quot;&gt;&lt;code&gt;const tuple = ['tesla', 'model 3', 'model X', 'model Y'] as const

type result = TupleToObject&amp;lt;typeof tuple&amp;gt; // expected { tesla: 'tesla', 'model 3': 'model 3', 'model X': 'model X', 'model Y': 'model Y'}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;background-color: #f6e199; font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;b&gt;&amp;nbsp;풀이&amp;nbsp;&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;배열에 있는 모든 값들을 얻어 새 객체의 키와 값으로 만들어야합니다.&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: 'Noto Sans Demilight', 'Noto Sans KR';&quot;&gt;&lt;code&gt;T[number]&lt;/code&gt;(인덱스 타입)을 이용해서 기존의 원소를 키와 값으로 하는 새로운 타입을 만들 수 있습니다.&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;scala&quot;&gt;&lt;code&gt;type TupleToObject&amp;lt;T extends readonly PropertyKey[]&amp;gt; = {[K in T[number]] : K}&lt;/code&gt;&lt;/pre&gt;</description>
      <category>TypeScript/Type Challenges</category>
      <category>TS</category>
      <category>Tuple to Object</category>
      <category>Type Challenges</category>
      <category>Typescript</category>
      <author>후끈후끈</author>
      <guid isPermaLink="true">https://likelacoste.tistory.com/53</guid>
      <comments>https://likelacoste.tistory.com/53#entry53comment</comments>
      <pubDate>Wed, 9 Nov 2022 10:50:41 +0900</pubDate>
    </item>
    <item>
      <title>읽기 전용 타입 - readonly, Readonly&amp;lt;T&amp;gt;</title>
      <link>https://likelacoste.tistory.com/52</link>
      <description>&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif; color: #000000;&quot;&gt;해당 값의 속성을 읽기 전용으로 설정해주는 타입시스템 기능입니다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif; color: #000000;&quot;&gt;함수가 매개변수로 받는 값을 변경 없이 그대로 사용해야할 때 적합합니다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif; color: #000000;&quot;&gt;외부에서 호출이 가능하지만 값의 변경은 불가능하므로, 값을 변경하기 위해서는 값을 초기화해줘야 합니다.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre class=&quot;d&quot;&gt;&lt;code&gt;interface Todo{
  readonly title: string;
  body: string;
}

const todo: Todo = {
  title: &quot;중요한 일정&quot;,
  body: &quot;병원가기&quot;
}

todo.title = &quot;오늘 안에 해야할 일&quot;;
todo.body = &quot;옷정리&quot;;

// Cannot assign to 'title' because it is a read-only property.&lt;/code&gt;&lt;/pre&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&amp;nbsp;&lt;/h2&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&amp;nbsp;&lt;/h2&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;background-color: #f6e199; font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp;Readonly&amp;nbsp;&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif; color: #000000;&quot;&gt;Readonly은 집합의 모든 프로퍼티 읽기 전용(readonly)으로 설정한 타입을 생성하기 때문에 생성된 타입의 프로퍼티를 재할당이 불가능합니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;background-color: #f6e199; font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&amp;nbsp;예시&amp;nbsp;&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;pre class=&quot;d&quot;&gt;&lt;code&gt;interface Todo{
  title: string;
  body: string;
}

const todo: Readonly&amp;lt;Todo&amp;gt; = {
  title: &quot;중요한 일정&quot;
  body: &quot;병원가기&quot;
}

todo.title = &quot;오늘 안에 해야할 일&quot;
// Cannot assign to 'title' because it is a read-only property.&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif; color: #000000;&quot;&gt;만약 배열을 읽기 전용으로 생성한다면 &lt;b&gt;ReadonlyArray&amp;lt;Type&amp;gt;&lt;/b&gt;을 사용하면 됩니다.&lt;/span&gt;&lt;/p&gt;
&lt;pre class=&quot;typescript&quot; data-ke-language=&quot;typescript&quot;&gt;&lt;code&gt;let numArray: ReadonlyArray&amp;lt;number&amp;gt; = [1, 2, 3];
console.log(numArray[1]); // 2

numArray.push(4);
// Property 'push' does not exist on type 'readonly number[]'.

numArray[0] = 10;
// Index signature in type 'readonly number[]' only permits reading.&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;&lt;b&gt;참조&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;&lt;b&gt;&lt;a href=&quot;https://www.typescriptlang.org/ko/docs/handbook/utility-types.html#readonlytype&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://www.typescriptlang.org/ko/docs/handbook/utility-types.html#readonlytype&lt;/a&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1667355594642&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;Documentation - Utility Types&quot; data-og-description=&quot;Types which are globally included in TypeScript&quot; data-og-host=&quot;www.typescriptlang.org&quot; data-og-source-url=&quot;https://www.typescriptlang.org/ko/docs/handbook/utility-types.html#readonlytype&quot; data-og-url=&quot;https://www.typescriptlang.org/ko/docs/handbook/utility-types.html#readonlytype&quot; data-og-image=&quot;&quot;&gt;&lt;a href=&quot;https://www.typescriptlang.org/ko/docs/handbook/utility-types.html#readonlytype&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://www.typescriptlang.org/ko/docs/handbook/utility-types.html#readonlytype&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url();&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;Documentation - Utility Types&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Types which are globally included in TypeScript&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;www.typescriptlang.org&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;&lt;b&gt;&lt;a href=&quot;https://radlohead.gitbook.io/typescript-deep-dive/type-system/readonly&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://radlohead.gitbook.io/typescript-deep-dive/type-system/readonly&lt;/a&gt;&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1667355546155&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;읽기 전용(readonly) - TypeScript Deep Dive&quot; data-og-description=&quot;기본적으로 readonly는 내가 속성을 변경하지 못함을 보장하지만, 객체를 다른 사람에게 넘길 경우에는 이것이 보장되지 않고 그 다른 사람은 객체의 속성을 변경할 수 있습니다 (타입 호환성 문&quot; data-og-host=&quot;radlohead.gitbook.io&quot; data-og-source-url=&quot;https://radlohead.gitbook.io/typescript-deep-dive/type-system/readonly&quot; data-og-url=&quot;https://radlohead.gitbook.io/typescript-deep-dive/type-system/readonly&quot; data-og-image=&quot;&quot;&gt;&lt;a href=&quot;https://radlohead.gitbook.io/typescript-deep-dive/type-system/readonly&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://radlohead.gitbook.io/typescript-deep-dive/type-system/readonly&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url();&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;읽기 전용(readonly) - TypeScript Deep Dive&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;기본적으로 readonly는 내가 속성을 변경하지 못함을 보장하지만, 객체를 다른 사람에게 넘길 경우에는 이것이 보장되지 않고 그 다른 사람은 객체의 속성을 변경할 수 있습니다 (타입 호환성 문&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;radlohead.gitbook.io&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>TypeScript/TS</category>
      <category>readonly</category>
      <category>ReadonlyArray</category>
      <category>TS</category>
      <category>Typescript</category>
      <author>후끈후끈</author>
      <guid isPermaLink="true">https://likelacoste.tistory.com/52</guid>
      <comments>https://likelacoste.tistory.com/52#entry52comment</comments>
      <pubDate>Wed, 2 Nov 2022 11:27:26 +0900</pubDate>
    </item>
    <item>
      <title>[7] Readonly</title>
      <link>https://likelacoste.tistory.com/51</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000; background-color: #f6e199;&quot;&gt;&lt;b&gt;&amp;nbsp;문제&amp;nbsp;&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;T의 모든 프로퍼티를 읽기 전용(재할당 불가)으로 바꾸는 내장 제네릭 Readonly를 사용하지 않고 구현하세요.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000; background-color: #f6e199;&quot;&gt;&lt;b&gt;&amp;nbsp;예시&amp;nbsp;&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;pre class=&quot;dts&quot;&gt;&lt;code&gt;interface Todo {
  title: string;
  description: string;
}

const todo: MyReadonly&amp;lt;Todo&amp;gt; = {
  title: &quot;Hey&quot;,
  description: &quot;foobar&quot;
}

todo.title = &quot;Hello&quot; // Error: cannot reassign a readonly property
todo.description = &quot;barFoo&quot; // Error: cannot reassign a readonly property&lt;/code&gt;&lt;/pre&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&amp;nbsp;&lt;/h2&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000; background-color: #f6e199;&quot;&gt;&lt;b&gt;&amp;nbsp;풀이&amp;nbsp;&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;pre class=&quot;elm&quot;&gt;&lt;code&gt;type MyReadonly&amp;lt;T&amp;gt; = {
  readonly [key in keyof T]: T[key]
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&amp;nbsp;&lt;/h2&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;background-color: #f6e199;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;&amp;nbsp;Readonly&amp;nbsp;&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;pre class=&quot;excel&quot;&gt;&lt;code&gt;type MyReadonly&amp;lt;T&amp;gt; = Readonly&amp;lt;T&amp;gt;;&lt;/code&gt;&lt;/pre&gt;</description>
      <category>TypeScript/Type Challenges</category>
      <category>readonly</category>
      <category>TS</category>
      <category>Type Challenges</category>
      <category>Typescript</category>
      <author>후끈후끈</author>
      <guid isPermaLink="true">https://likelacoste.tistory.com/51</guid>
      <comments>https://likelacoste.tistory.com/51#entry51comment</comments>
      <pubDate>Wed, 2 Nov 2022 10:42:03 +0900</pubDate>
    </item>
    <item>
      <title>순수함수란 무엇인가? (Side Effect)</title>
      <link>https://likelacoste.tistory.com/50</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;순수함수는 함수형 프로그래밍에서 많이 사용되는 개념으로, 오직 함수의 입력만이 함수의 결과에 영향을 주는 함수를 의미합니다. 순수함수가 되기 위해서는 사이드 이팩트가 없어야 합니다.&lt;/span&gt;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;Side Effect란?&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;&lt;span style=&quot;color: #000000;&quot;&gt;함수의 입력 외에도 함수의 결과에 영향을 미치는 요인을 말합니다. 대표적으로 네트워크 요청, API 호출이 Side Effect 입니다.&lt;/span&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;자바스크립트에서 순수함수를 만들기 위해서는 데이터의 불변성을 유지하는 것이 중요합니다. 함수의 전달인자로 참조 자료형이 전달되는 경우, 의도치 않게 해당 객체 자체를 바꾸는 사이드 이펙트를 만들 수 있는데, 이는 해당 데이터의 불변성을 손상시킬 수 있습니다. 그래서 배열의 불변성을 보장하는&amp;nbsp; map, filter, reduce 등을 많이 사용합니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>Memo</category>
      <category>javascript</category>
      <category>js</category>
      <category>side effect</category>
      <category>순수함수</category>
      <author>후끈후끈</author>
      <guid isPermaLink="true">https://likelacoste.tistory.com/50</guid>
      <comments>https://likelacoste.tistory.com/50#entry50comment</comments>
      <pubDate>Tue, 1 Nov 2022 11:51:45 +0900</pubDate>
    </item>
    <item>
      <title>Utility Types(유틸리티 타입) - Partial, Required, Pick, Omit</title>
      <link>https://likelacoste.tistory.com/49</link>
      <description>&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif; color: #000000;&quot;&gt;TypeScript는 일반적인 타입 변환을 쉽게 하기 위해서 몇가지 유틸리티 타입을 제공합니다. 이러한 유틸리티는 전역으로 사용할 수 있습니다.&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif; color: #000000;&quot;&gt;유틸리티 타입은 제네릭 타입이라고도 불리며, 타입 정의를 더욱 짧고 간단하게 사용할 수 있습니다.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;background-color: #c1bef9;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif; color: #000000;&quot;&gt;Partial&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif; color: #000000;&quot;&gt;Partial Type은 집합의 모든 프로퍼티를 선택적으로 타입을 생성할 수 있습니다. &lt;/span&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif; color: #000000;&quot;&gt;이 유틸리티는 주어진 타입의 모든 하위 타입 집합을 나타내는 타입을 반환합니다.(부분집합)&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif; color: #000000;&quot;&gt;예시&lt;/span&gt;&lt;/b&gt;&lt;/h3&gt;
&lt;pre class=&quot;groovy&quot;&gt;&lt;code&gt;interface User {
  email: string;
  password: number;
}

type Person = Partial&amp;lt;Address&amp;gt;;
const me: MyInfo = {}; // 가능
const you: YouInfo = { email: &quot;abcd@gmail.com&quot; }; // 가능
const all: UserInfo = { email: &quot;abcd@gmail.com&quot;, password: 1234 }; // 가능&lt;/code&gt;&lt;/pre&gt;
&lt;pre class=&quot;typescript&quot;&gt;&lt;code&gt;interface Product {
  id: number;
  name: string;
  price: number;
  brand: string;
  stock: number;
}

// Partial을 사용하면 인자에 type으로 Product의 모든 정보를 다 넣지 않아도 된다.
// 상품의 정보를 업데이트 (put) 함수 -&amp;gt; id, name 등등 어떤 것이든 인자로 들어올 수 있다.
interface UpdateProduct {
  id?: number;
  name?: string;
  price?: number;
  brand?: string;
  stock?: number;
}
// Partial을 사용하지 않으면 위와 같이 정의할 수도 있다.
// 그러나 같은 인터페이스를 또 정의하는 것을 피하기 위해서 Partial을 사용한다.
function updateProductItem(prodictItem: Partial&amp;lt;Product&amp;gt;) {
  // Partial&amp;lt;Product&amp;gt;이 타입은 UpdateProduct 타입과 동일하다
}&lt;/code&gt;&lt;/pre&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&amp;nbsp;&lt;/h3&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif; color: #000000;&quot;&gt;응용하기&lt;/span&gt;&lt;/b&gt;&lt;/h3&gt;
&lt;pre class=&quot;rust&quot;&gt;&lt;code&gt;// 아래 인터페이스를 다른 방법으로 아래와 같이 구현할 수 있다.

interface UserProfile {
  username: string;
  email: string;
  profilePhotoUrl: string;
}

type partials = Partial&amp;lt;UserProfile&amp;gt;

// #1
type UserProfileUpdate = {
  username?: UserProfile[&quot;username&quot;];
  email: UserProfile[&quot;email&quot;];
  profilePhotoUrl?: UserProfile[&quot;profilePhotoUrl&quot;];
};

// #2 - 맵드 타입
type UserProfileUpdate = {
  // index signatures
  [p in 'username' | 'email' | 'profilePhotoUrl']? = UserProfile[p]
};

type UserProfileKeys = keyof UserProfile // 'username' | 'email' | 'profilePhotoUrl'

// #3
type UserProfileUpdate = {
  [p in key of UserProfile]? = UserProfile[p]
};

// #4 - 파셜
type RealPartial&amp;lt;T&amp;gt; = {
  [p in key of T]? = T[p]
};&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&amp;nbsp;&lt;/h2&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;background-color: #c1bef9;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif; color: #000000;&quot;&gt;Required&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif; color: #000000;&quot;&gt;타입 집합의 모든 프로퍼티를 필수로 설정한 타입을 정의합니다.(Partial의 반대)&lt;/span&gt;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&amp;nbsp;&lt;/h3&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif; color: #000000;&quot;&gt;예시&lt;/span&gt;&lt;/b&gt;&lt;/h3&gt;
&lt;pre class=&quot;nimrod&quot;&gt;&lt;code&gt;interface UserProfile {
  username?: string;
  email?: string;
  profilePhotoUrl?: string;
}

const user1: UserProfile = {
  username: &quot;Kim&quot;
}

const user2: Required&amp;lt;UserProfile&amp;gt; = {
  username: &quot;Kim&quot;
} 

// Type '{ username: string; }' is missing the following properties from type 'Required&amp;lt;UserProfile&amp;gt;': email, profilePhotoUrl
&lt;/code&gt;&lt;/pre&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&amp;nbsp;&lt;/h2&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&amp;nbsp;&lt;/h2&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;background-color: #c1bef9;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif; color: #000000;&quot;&gt;Pick&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif; color: #000000;&quot;&gt;Pick Type은 특정 타입에서 몇 개의 속성을 선택하여 타입을 정의합니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif; color: #000000;&quot;&gt;예시&lt;/span&gt;&lt;/b&gt;&lt;/h3&gt;
&lt;pre class=&quot;typescript&quot;&gt;&lt;code&gt;interface Product{
  id: number;
  name: string;
  price: number;
  brand: string;
  stock: number;
}

// 상품 목록 받아오기
function fetchProdcut():Promise&amp;lt;Product[]&amp;gt;{
  // id, name, price, brand, stock 모두를 써야 한다.
}

type ShoppingItem = Pick&amp;lt;Product, &quot;id&quot; | &quot;name&quot; | &quot;price&quot;&amp;gt;;

function displayProductDetail(shoppingItem: ShoppingItem){
  // id, name, price의 일부만 사용 or 별도의 속성이 추가되는 경우가 있음
  // 인터페이스의 모양이 달라질 수 있다
}

// 3. Partial
interface UpdateProduct {
  id?: number;
  name?: string;
  price?: number;
  brand?: string;
  stock?: number;
}

function updateProductItem(prodictItem: Partial&amp;lt;Product&amp;gt;) {
  // Partial&amp;lt;Product&amp;gt;이 타입은 UpdateProduct 타입과 동일하다
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&amp;nbsp;&lt;/h2&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;background-color: #c1bef9;&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif; color: #000000;&quot;&gt;Omit&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif; color: #000000;&quot;&gt;특정 속성만 제거한 타입을 정의합니다. (Pick의 반대)&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif; color: #000000;&quot;&gt;예시&lt;/span&gt;&lt;/b&gt;&lt;/h3&gt;
&lt;pre class=&quot;dts&quot;&gt;&lt;code&gt;interface Product {
  id: number;
  name: string;
  price: number;
  brand: string;
  stock: number;
}

type shoppingItem = Omit&amp;lt;Product, &quot;stock&quot;&amp;gt;;

const apple: Omit&amp;lt;Product, &quot;stock&quot;&amp;gt; = {
  id: 1,
  name: &quot;Kim&quot;,
  price: 1000,
  brand: &quot;del&quot;
};
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;참조&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;a href=&quot;https://www.typescriptlang.org/ko/docs/handbook/utility-types.html&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://www.typescriptlang.org/ko/docs/handbook/utility-types.html&lt;/a&gt;&lt;/b&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1667020703920&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;Documentation - Utility Types&quot; data-og-description=&quot;Types which are globally included in TypeScript&quot; data-og-host=&quot;www.typescriptlang.org&quot; data-og-source-url=&quot;https://www.typescriptlang.org/ko/docs/handbook/utility-types.html&quot; data-og-url=&quot;https://www.typescriptlang.org/ko/docs/handbook/utility-types.html&quot; data-og-image=&quot;&quot;&gt;&lt;a href=&quot;https://www.typescriptlang.org/ko/docs/handbook/utility-types.html&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://www.typescriptlang.org/ko/docs/handbook/utility-types.html&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url();&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;Documentation - Utility Types&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Types which are globally included in TypeScript&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;www.typescriptlang.org&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://kyounghwan01.github.io/blog/TS/fundamentals/utility-types/#%E1%84%8B%E1%85%A8%E1%84%89%E1%85%B5-2&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://kyounghwan01.github.io/blog/TS/fundamentals/utility-types/#%E1%84%8B%E1%85%A8%E1%84%89%E1%85%B5-2&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1667020711989&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;typescript - 유틸리티 타입 (Partial, Omit, Pick)&quot; data-og-description=&quot;typescript - 유틸리티 타입 (Partial, Omit, Pick), 타입스크립트, ts&quot; data-og-host=&quot;kyounghwan01.github.io&quot; data-og-source-url=&quot;https://kyounghwan01.github.io/blog/TS/fundamentals/utility-types/#%E1%84%8B%E1%85%A8%E1%84%89%E1%85%B5-2&quot; data-og-url=&quot;https://kyounghwan01.github.io/blog/TS/Fundamentals/utility-types/&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/bUSw4X/hyQn3qR8Pn/AT9zpsFGR1XPKPIAFCT2Bk/img.png?width=460&amp;amp;height=460&amp;amp;face=0_0_460_460&quot;&gt;&lt;a href=&quot;https://kyounghwan01.github.io/blog/TS/fundamentals/utility-types/#%E1%84%8B%E1%85%A8%E1%84%89%E1%85%B5-2&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://kyounghwan01.github.io/blog/TS/fundamentals/utility-types/#%E1%84%8B%E1%85%A8%E1%84%89%E1%85%B5-2&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/bUSw4X/hyQn3qR8Pn/AT9zpsFGR1XPKPIAFCT2Bk/img.png?width=460&amp;amp;height=460&amp;amp;face=0_0_460_460');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;typescript - 유틸리티 타입 (Partial, Omit, Pick)&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;typescript - 유틸리티 타입 (Partial, Omit, Pick), 타입스크립트, ts&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;kyounghwan01.github.io&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>TypeScript/TS</category>
      <category>OMIT</category>
      <category>partial</category>
      <category>Pick</category>
      <category>required</category>
      <category>TS</category>
      <category>Typescript</category>
      <author>후끈후끈</author>
      <guid isPermaLink="true">https://likelacoste.tistory.com/49</guid>
      <comments>https://likelacoste.tistory.com/49#entry49comment</comments>
      <pubDate>Sat, 29 Oct 2022 14:20:38 +0900</pubDate>
    </item>
    <item>
      <title>[4] Pick</title>
      <link>https://likelacoste.tistory.com/48</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;문제&lt;/span&gt;&lt;/b&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;T에서 K 프로퍼티만 선택해 새로운 오브젝트 타입을 만드는 내장 제네릭 Pick&amp;lt;T, K&amp;gt;을 이를 사용하지 않고 구현하세요.&lt;/span&gt;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&amp;nbsp;&lt;/h2&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;예시&lt;/span&gt;&lt;/b&gt;&lt;/h2&gt;
&lt;pre class=&quot;routeros&quot;&gt;&lt;code&gt;interface Todo {
  title: string
  description: string
  completed: boolean
}

type TodoPreview = MyPick&amp;lt;Todo, 'title' | 'completed'&amp;gt;

const todo: TodoPreview = {
    title: 'Clean room',
    completed: false,
}&lt;/code&gt;&lt;/pre&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&amp;nbsp;&lt;/h2&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;풀이&lt;/span&gt;&lt;/b&gt;&lt;/h2&gt;
&lt;pre class=&quot;scala&quot;&gt;&lt;code&gt;type MyPick&amp;lt;T, K extends keyof T&amp;gt; = {
    [P in K]: T[P];
}&lt;/code&gt;&lt;/pre&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&amp;nbsp;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style5&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&amp;nbsp;&lt;/h3&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;Pick&amp;lt;Type, Keys&amp;gt;&lt;/span&gt;&lt;/b&gt;&lt;/h3&gt;
&lt;pre class=&quot;routeros&quot;&gt;&lt;code&gt;interface Todo {
  title: string;
  description: string;
  completed: boolean;
}

type TodoPreview = Pick&amp;lt;Todo, &quot;title&quot; | &quot;completed&quot;&amp;gt;;

const todo: TodoPreview = {
  title: &quot;Clean room&quot;,
  completed: false,
};&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>TypeScript/Type Challenges</category>
      <category>TS</category>
      <category>Type</category>
      <category>Type Challenges</category>
      <category>Typescript</category>
      <author>후끈후끈</author>
      <guid isPermaLink="true">https://likelacoste.tistory.com/48</guid>
      <comments>https://likelacoste.tistory.com/48#entry48comment</comments>
      <pubDate>Sat, 29 Oct 2022 13:30:56 +0900</pubDate>
    </item>
    <item>
      <title>HTTP Messages</title>
      <link>https://likelacoste.tistory.com/47</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;HTTP 메세지는 클라이언트와 서버 사이에서 데이터가 교환되는 방식입니다. HTTP 메시지는 Requests(요청)와 Response(응답) 타입으로 나눠지는데, 이 둘은 유사한 구조를 가지고 있습니다. 각각의 메세지는 어떠한 구조로 되어 있는지 함께 알아보도록 하겠습니다.&lt;/span&gt;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;HTTP Requests&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;HTTP Requests는 클라이언트가 서버에게 보내는 요청 메세지 입니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;&lt;b&gt;Start&lt;/b&gt; &lt;b&gt;line&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;Start line에는 HTTP method와 Request target, HTTP version이 있습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;- HTTP method : GET, POST, PUT, DELETE 등(GET은 리소스 받기, POST는 데이터를 서버로 전송, PUT 리소스에 대한 변경, DELETE 리소스 삭제)&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;- Request target : HTTP Request가 전송되는 목표 주소(URL이나 URI 또는 프로토콜, 포트, 도메인의 절대 경로 등)&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;- HTTP version : version에 따라 메시지 구조가 달라지기 때문에, 버전을 함께 입력합니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;Headers&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;헤더의 이름(대소문자 구분이 없는 문자열), 콜론(:), 값을 입력합니다. 값은 헤더에 따라 다르며, 여러 종류의 헤더가 있습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;- General headers : 메시지 전체에 적용되는 헤더로, body를 통해 전송되는 데이터와는 관련이 없는 헤더&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;- Request headers : fetch를 통해 가져올 리소스나 클라이언트 자체에 대한 자세한 정보를 포함하는 헤더(User-Agent, Accept-Type, Accept-Language와 같은 헤더는 요청을 보다 구체화 할 수 있습니다.)&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;- Repressentation headers : 이전에는 Entity headers로 불렸으며, body에 담긴 리소스의 정보(콘텐츠의 길이, MIME 타입 등)를 포함하는 헤더입니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;WdUM6NPoP-1620275406066.png&quot; data-origin-width=&quot;872&quot; data-origin-height=&quot;280&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/7jssu/btrPw0JeN3W/CnXcqeQozIT1zX5VfZn9Q1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/7jssu/btrPw0JeN3W/CnXcqeQozIT1zX5VfZn9Q1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/7jssu/btrPw0JeN3W/CnXcqeQozIT1zX5VfZn9Q1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F7jssu%2FbtrPw0JeN3W%2FCnXcqeQozIT1zX5VfZn9Q1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;666&quot; height=&quot;214&quot; data-filename=&quot;WdUM6NPoP-1620275406066.png&quot; data-origin-width=&quot;872&quot; data-origin-height=&quot;280&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;Host: 요청하려는 서버 호스트 이름과 포트번호&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;User-agent : 클라이언트 프로그램 정보(이 정보를 통해 서버는 클라이언트 프로그램(브라우저)에 맞는 최적의 데이터를 보내줄 수 있다.)&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;Accept : 클라이언트가 처리 가능한 미디어 타입 종류&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;Referer : 바로 직전에 머물렀던 웹 링크 주소&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;If-Modified-Since : 여기에 쓰여진 시간 이후로 변경된 리소스 취득(페이지가 수정되었으면 최신 페이지로 교체한다.)&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;Authorization : 인증 토큰을 서버로 보낼 때 쓰이는 헤더&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;Origin : 서버로 Post 요청을 보낼 때 요청이 어느 주소에 시작되었는지 나타내는 값(만약에 이 값으로 요청을 보낸 주소와 받는 주소가 다르면 CORS(Cross-Origin Resource Sharing) 에러가 발생한다.)&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;Cookie : 쿠키(값이 key-value로 표현된다.)&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&amp;nbsp;&lt;/h3&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;Body&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;모든 요청에 body가 필요하지는 않습니다. GET, HEAD, DELETE, OPTIONS처럼 서버에 리소스를 요청하는 경우에는 body가 필요하지 않습니다. 반면에 POST, PUT과 같은 요청은 데이터를 업데이트하기 위해서 사용하기 때문에 body가 필요합니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;- Single-resource bodies(단일-리소스 본문) : 헤더 두개(Content-Type과 Content-Length)로 정의된 단일 파일로 구성&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;- Multiple-resource bodies(다중-리소스 본문) : 여러 파트로 구성된 본문에서는 각 파트마다 다른 정보를 지님(보통 HTML form과 관련있다.)&lt;/span&gt;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&amp;nbsp;&lt;/h2&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;HTTP Responses&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;HTTP Responses는 서버가 클라이언트에게 보내는 메시지입니다. HTTP Request와는 다르게 응답의 첫 줄을 Status line이라고 부릅니다.&lt;/span&gt;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&amp;nbsp;&lt;/h3&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;&lt;b&gt;Status line&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;Status line에는 HTTP version과 Status code, Status text가 있습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;- HTTP version : 현재 프로토콜의 버전(HTTP/1.1)&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;- Status code : 요청의 결과(200, 302, 404 등)&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;- Status text : 상태 코드에 대한 설명&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;ex) HTTP/1.1 404 Not Found&lt;/span&gt;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&amp;nbsp;&lt;/h3&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;Headers&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;응답에 들어가는 헤더는 요청 헤더와 동일한 구조를 가지고 있습니다. 대소문자 구분 없는 문자열, 콜론(:), 값을 입력하며, 값은 헤더에 따르 다릅니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;- General headers : 메시지 전체에 적용되는 헤더로, body를 통해 전송되는 데이터와는 관련이 없는 헤더&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;- Response headers : 위치 또는 서버 자체에 대한 정보(이름, 버전 등)와 같이 응답에 대한 부가적인 정보를 갖는 헤더로, Vary, Accept-Ranges와 같이 상태 줄에 넣기에는 공간이 부족했던 추가 정보를 제공&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;- Representation headers : 이전에는 Entity headers로 불렀으며, body에 담긴 리소스의 정보(콘텐츠 길이, MIME 타입 등)를 포함하는 헤더&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;CVLWG7X3Z-1620275557974.png&quot; data-origin-width=&quot;805&quot; data-origin-height=&quot;344&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/5EupU/btrPt64zoli/BzZDYlckI9lIMjcIkTusi1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/5EupU/btrPt64zoli/BzZDYlckI9lIMjcIkTusi1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/5EupU/btrPt64zoli/BzZDYlckI9lIMjcIkTusi1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F5EupU%2FbtrPt64zoli%2FBzZDYlckI9lIMjcIkTusi1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;666&quot; height=&quot;285&quot; data-filename=&quot;CVLWG7X3Z-1620275557974.png&quot; data-origin-width=&quot;805&quot; data-origin-height=&quot;344&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;Location : 301, 302 상태코드일 때만 볼 수 있는 Header(서버의 응답이 다른 곳에 있다고 알려주면서 해당 위치(URI)를 지정합니다.)&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;Server : 웹 서버의 종류&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;Age : max-age (시간내에서 얼마나 흘렀는지 초 단위로 알려주는 값입니다.)&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;Referrer-policy : 서버 referrer 정책을 알려주는 값 (ex) origin, no-referrer, unsafe-url)&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;WWW-Authenticate : 사용자 인증이 필요한 자원을 요구할 시 , 서버가 제공하는 인증 방식&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;Proxy-Authenticate : 요청한 서버가 프록시 서버인 경우 유저 인증을 위한 값&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&amp;nbsp;&lt;/h3&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic';&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;Body&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;요청과 동일하게 모든 응답에 body가 필요하지는 않으며, 201, 204와 같은 상태 코드를 가지는 응답에도 body가 필요하지 않습니다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;- Single-resource bodies(단일-리소스 본문) :&lt;/span&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;길이가 알려진 단일-리소스 본문은 두 개의 헤더(Content-Type, Content-Length)로 정의&lt;/span&gt;&lt;/li&gt;
&lt;li&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;길이를 모르는 단일 파일로 구성된 단일-리소스 본문은 Transfer-Encoding이 chunked 로 설정되어 있으며, 파일은 chunk로 나뉘어 인코딩되어 있다.&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Nanum Gothic'; color: #000000;&quot;&gt;- Multiple-resource bodies(다중-리소스 본문) : 서로 다른 정보를 담고 있는 body&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>네트워크</category>
      <category>HTTP</category>
      <category>HTTP Message</category>
      <category>HTTP Request</category>
      <category>http response</category>
      <category>HTTP 메시지</category>
      <author>후끈후끈</author>
      <guid isPermaLink="true">https://likelacoste.tistory.com/47</guid>
      <comments>https://likelacoste.tistory.com/47#entry47comment</comments>
      <pubDate>Tue, 25 Oct 2022 12:37:33 +0900</pubDate>
    </item>
  </channel>
</rss>