이벤트 핸들링

DOM의 모든 element는 event target을 상속한 node다. Event target은 DOM 인터페이스로, 이벤트를 받을 수 있고, 이벤트에 대한 리스너를 가질 수 있다. 이벤트가 발생하면 event object를 만들어서 등록한 콜백함수에 전달한다.

 

method action
addEventListner 특정한 이벤트에 event handler를 등록. 여러번 호출하면 핸드러를 여러개 붙일 수 있다.
removeEventListner Event target에 등록된 이벤트 리스너를 제거
dispatchEvent Event target에 이벤트를 발생시킴

Event object(이벤트 객체)

이벤트에 관한 상세한 정보를 가지고 있는 객체

이벤트가 발생하면 브라우저는 이벤트 객체라는 것을 만들어 핸들러 함수에 인수 형태로 전달한다.

 

property  
event.type 발생한 이벤트의 종류
event.currentTarget 이벤트를 처리하는 요소. 화살표 함수를 사용했거나 함수를 다른 곳에 바인딩한 경우에 이벤트가 처리되는 요소 정보를 얻을 수 있다.
event.target 이벤트가 발생한 가장 안쪽의 요소

버블링과 캡처링

DOM 이벤트에서 정의한 이벤트 흐름 3단계

  1. 캡처링 - 이벤트가 하위 요소로 전파
  2. 타깃 - 이벤트가 실제 타깃 요소에 전달되는 단계
  3. 버블링 단계 - 이벤트가 상위 요소로 전파되는 단계

캡처링 Capturing

최상위 조상에서 이벤트가 시작해 아래로 전파되는 단계이다. 캡처링 단계를 이용해야 하는 경우는 흔치 않다.

버블링 Bubbling

자식 요소에서 이벤트가 발생하면 부모 요소까지 이벤트가 전파되는 것을 말한다. 즉 한 요소에 이벤트가 발생하면, 부모 요소의 등록된 핸들러가 동작한다. 가장 최상단의 조상 요소까지 이 과정을 반복하면서 요소 각각에 할당된 핸들러가 동작한다. 거의 모든 이벤트는 버블링되지만 focus 이벤트와 같이 버블링 되지 않는 이벤트도 있다.

  • event.target : 실제 이벤트가 시작된 요소. 버블링이 진행되어도 변하지 않는다.
  • event.currentTarget : '현재' 요소. 현재 실행 중인 핸들러가 할당된 요소(=this)

버블링을 중단하기 위해서 event.stopPropagation()을 사용할 수 있지만 꼭 필요한 경우가 아니면 사용하지 않는게 좋다. 클릭 이벤트를 분석하기 위해 이벤트 리스너를 등록해둔 경우, stopPropagation을 사용하면 분석 로직이 동작하지 않을 수 있다.
이벤트 핸들러가 원하는 상황에서만 동작하도록 코드를 작성하는 것이 더 좋다.

const addButton = document.querySelector('.add-button')
const buttonParent = document.querySelector('.parent-div')

buttonParent.addEventListner('click',(e)=>{
    if(e.currentTarget !== e.target){
        return;
    }

      console.log('div 이벤트')
})

addButton.addEventListner('click',(e)={
    console.log('버튼 클릭')
})

이벤트 위임

비슷한 방식으로 여러 요소를 다뤄야 할 때, 각각의 자식요소에 이벤트를 할당하지 않고, 공통 조상에 이벤트 핸들러를 할당해 여러 요소를 다룰 수 있다. 성능면에서도 이 방법이 더 좋다.

각 요소에 이벤트 할당

<ul>
    <li>우유</li>
      <li>두유</li>
      <li>커피</li>
</ul>
const items = document.querySelectAll('li')

items.forEach(item=>{
    item.addEventListner('click',onClickItem)
})

const onClickItem = (e)=>{
    console.log(e.innerText)
}

이벤트 위임

const list = document.querySelector('ul')

list.addEventListner('click',onClickItem)

const onClickItem = (e)=>{
    if(e.target.tagName === 'li'){
        console.log(e.target.innerText)
    }
}

이벤트의 기본 동작

많이 이벤트가 발생 즉시 브라우저에 의해 특정 동작을 자동으로 수행한다.

  • a 태그 : 링크를 클릭하면 해당 URL로 이동
  • submit : 서버에 form 데이터가 전송

자바스크립트를 사용해 직접 동작을 구현해야하는 경우 기본적인 동작을 막는 방법은 두 가지다.

  • event.preventDefault() 메서드를 사용
  • addEventListner가 아닌 on 방식으로 할당되었다면 false를 반환
       <a href='/' onclick="return false">하이</a>    

addEventLister의 passive:true 옵션은 브라우저에게 preventDefault()를 호출하지 않겠다고 알리는 역할을 한다. 예를 들어 모바일 기기에서 touchmove와 같은 이벤트는 스크롤링을 발생시키는데 preventDefault()를 사용하면 스크롤링을 막을 수 있다. 브라우저는 스크롤링을 발생시키는 이벤트를 감지했을 때 모든 핸들러를 처리하는데, preventDefault가 어디에서도 호출되지 않은 것을 확인하고 스크롤링을 진행한다. 이 과정에서 지연과 버벅임이 발생하는데 passive:true 옵션을 주면 핸들러가 스크롤링을 취소하지 않을 것이라는 정보를 브라우저에게 알려줘서, 브라우저는 화면을 최대한 자연스럽게 스크롤링을 처리할 수 있다. passive 옵션은 기본적으로 정해져있기 때문에 임의로 조작하지 않는 편이 좋다.

기타

  • keypress 이벤트는 deprecated
  • keydown 이벤트는 브라우저가 입력을 처리하기 전에 발생, keyup 이벤트는 브라우저가 입력을 처리한 후에 발생
  • form을 이용하면 여러 input의 value를 한번에 받아올 수 있다

📑 referece

'Javascript' 카테고리의 다른 글

실행 컨텍스트  (0) 2021.11.28
자바스크립트 런타임환경  (0) 2021.09.11
CRP(Critical render path, 브라우저 렌더링 순서)  (0) 2021.08.21
Web API  (0) 2021.08.12
DOM  (0) 2021.08.10

Critical rendering path

브라우저가 HTML, CSS, Javascdript를 화면에 픽셀로 변환하는 일련의 단계

CRP는 DOM, CSSOM, Render tree, Layout, Paint를 포함한다. CRP를 이해하고 최적화하는 것은 뛰어난 사용자 상호작용을 보장하며 버벅거림을 피할 수 있도록 하고, 1초당 60프레임에 리플로우와 리페인트가 발생할 수 있도록 하는데 중요하다.

브라우저는 요청 후에 서버로부터 HTML을 응답받는다. 응답받은 HTML을 분석하고, 수신된 바이트를 DOM트리로 변환한다. 브라우저는 스타일시트, 스크립트 또는 외부 자원(이미지 참조 등)에 대한 링크를 찾을때마다 요청을 한다.(불러온 에셋을 다룰 때까지 나머지 HTML을 분석 작업은 중단됨) CSSOM이 완료되면 브라우저는 렌더 트리를 생성하고 보여지는 컨텐츠를 위해 스타일을 계산한다. 렌더트리가 완료된 후 모든 렌더 트리 요소들에 대한 위치와 크기가 정의된 레이아웃이 만들어진다.

 

Construction Construction
DOM->CSSOM -> Render Tree Layout -> Paint -> Composition

 

1. DOM

  • DOM Tree는 완전하게 파싱된 HTML 페이지의 Object 표현이다.
  • html로부터 시작해 각 element, text에 대한 node가 만들어진다.
  • DOM Tree 생성은 점진적으로 진행된다. 페이지에 내용을 표시하기 위해 문서 전체를 로드할 필요가 없다.
  • CSS와 javascript 로드시에 페이지의 렌더링을 차단할 수 있다.
  • 불필요한 tag나 wrapper는 사용하지 않고, div를 남용하는 대신 sementic 태그를 이용하는 것이 성능에 좋다.

2. CSSOM

  • DOM을 스타일링 하기 위한 페이지의 모든 스타일 정보
  • CSS는 상속과 덮어쓰기가 가능하기 때문에 CSS 전체가 파싱되기 전에 사용하면 잘못된 스타일이 적용될 수 있다.
  • 따라서 브라우저는 모든 CSS를 수신하고 처리할 때까지 페이지 렌더링을 막는다.
  • 구체적인 선택자보다 덜 구체적인 선택자가 더 빠르지만 성능차이가 크지는 않다.

3. Render Tree 만들기

  • DOM과 CSSOM이 합쳐진 것으로 페이지에서 최종적으로 렌더링할 내용을 나타내는 Tree
  • Render Tree는 오직 보여지는 node만 캡쳐한다.
    • 예] display:none 속성은 렌더트리에 포함되지 않는다.(visible:hidden은 포함됨)

4. Layout

  • 요소들이 페이지에서 배치되는 위치와 방법, 각 요소의 너비높이 그리고 서로 관련된 위치를 결정한다.
  • 뷰포트 메타 태그는 레이아웃의 너비를 정의한다.

<meta name="viewport" content="width=device-width, initial-scale=1">
  • 레이아웃은 디바이스가 회전하거나 브라우저의 사이즈가 조정될 때마다 발생한다.
  • 레아아웃의 성능은 DOM의 영향을 받는다. 노드의 수가 많을수록 레이아웃은 더 길어지며, 스크롤링 또는 다른 애니메이션이 있으면 레이아웃에 jank를 일으키는 병목현상이 발생할 수 있다.
  • 레아아웃 이벤트의 반복과 형성시간을 줄이기 위해서 일괄 업데이트를 해야하고, 박스 모델 속성을 애니메이션화 하지 말아야 한다.
  • 박스모델 : HTML 요소를 padding, border, margin, content 으로 구분하는 것.

5. Paint

  • 화면에 픽셀을 그리는 단계.
  • 렌더 트리가 생성되고 레이아웃이 나타나기 시작하면 화면에 픽셀을 그릴 수 있다.
  • load시에 전체 화면을 그리고, 이후에는 브라우저가 필요한 최소 영역만 다시 그리도록 최적화 되어있다
  • Layer 단위로 준비(z-index 등). 변화가 있을 때 해당 레이어만 수정하도록 최적화되어 있다.

6. Composition

  • 준비한 레이어를 화면에 놓는 과정

CRP 최적화 방법

  • 자원 로드 순서 관리
  • 파일 사이즈 줄이기
  • 자원 다운로드를 연기함으로써 중요 자원들의 수를 최소화
  • Operation 과정에서 layout, paint는 되도록 적게 발생해야 함
  • ex] element를 이동할 때 top, left 속성을 변경하면 layout+paint+composition이 다 발생하지만 translate를 이용할 경우 composition만 발생한다.

https://csstriggers.com/ 참고


📑 referece

'Javascript' 카테고리의 다른 글

실행 컨텍스트  (0) 2021.11.28
자바스크립트 런타임환경  (0) 2021.09.11
이벤트  (0) 2021.08.28
Web API  (0) 2021.08.12
DOM  (0) 2021.08.10

Web APIs

MDN - Web APIs

종류

  • DOM APIs
  • Network APIs
  • Graphics APIs
  • Audio/Video APIs
  • Device APIs
  • File APIs
  • Storage APIs
    등등등

브라우저 구조분석

  • 문서 객체 모델(Document Object Model, DOM) : 웹 페이지 내의 모든 콘텐츠를 객체로 나타내준다. document 객체는 페이지의 기존 진입점 역할을 한다.
  • 브라우저 객체 모델(Browser Object Model, BOM) : 문서 이외의 모든 것을 제어하기 위해 브라우저(호스트 환경)이 제공하는 추가 객체를 나타낸다.
    • navigator : 브라우저와 운영체제에 대한 정보를 제공한다.
    • location : 현재 URL을 읽을 수 있게 해주고 새로운 URL로 변경할 수 있다.

Document

브라우저의 좌표

getBoundingClientRect

  • element.getBoundigClientRect() 메서드는 elem을 감싸는 가장 작은 네모의 창 기준 좌표를 DOMRect 클래스의 객체 형태로 반환한다.
  • x와 y : 요소를 감싸는 네모창 기준 x,y
  • width와 height : 요소를 감싸는 네모의 너비, 높이
  • 창 기준 : clientX clientY
  • 문서 기준 : pageX pageY
  • top bottom : 요소를 감싸는 네모의위쪽 모서리, 아래쪽 모서리의 Y좌표
  • left right : 요소를 감싸는 네모의 왼쪽 모서리, 오른쪽 모서리의 X좌표
  • left = x
  • top = y
  • right = x + width
  • bottom = y + height

client, offset, page, screen의 차이

client : 스크롤을 무시하고 브라우저 페이지에서의 좌표
offset : 스크롤을 포함한 전체 문서를 기준으로 이벤트 대상 객체의 상대적 마우스 좌표
page : 스크롤 화면을 포함해 전체 문서 기준
screen: 모니터 화면에서의 좌표


reference

'Javascript' 카테고리의 다른 글

실행 컨텍스트  (0) 2021.11.28
자바스크립트 런타임환경  (0) 2021.09.11
이벤트  (0) 2021.08.28
CRP(Critical render path, 브라우저 렌더링 순서)  (0) 2021.08.21
DOM  (0) 2021.08.10

DOM(Document Object Model)

HTML이나 XML 문서의 프로그래밍 interface이다.

  • 문서의 구조화된 표현 제공
  • 프로그래밍 언어가 DOM 구조에 접근할 수 있는 방법을 제공해 문서를 표현하고, 저장하고, 조작하는 방법을 제공한다.

HTML이나 XML Document 구조를 바탕으로 요소들이 화면에 나타나고, 이벤트에 반응하고 값을 입력받는 등의 기능을 수행할 객체들로 실체화 된 형태를 의미한다. 구조화된 nodes와 property와 method를 갖고 있는 objets로 문서를 표현한다. 이들은 웹 페이지를 스크립트 또는 프로그래밍 언어들에서 사용될 수 있게 연결시켜주는 역할을 담당한다. DOM은 javascript를 이용해 명령을 받을 수 있지만 javascript 객체는 아니며, 언어에 종속되지 않고 DOM을 조작할 수 있다. (javascript, 파이썬 beautifulsoup 등) DOM은 웹 페이지의 객체 지향 표현이며, 자바스크립트와 같은 스크립팅 언어를 이용해 DOM을 수정할 수 있다.

Node


[https://velog.io/@mollog/%EA%B0%9D%EC%B2%B4%EC%A7%80%ED%96%A5-%EA%B0%9C%EB%85%90-%EC%A0%95%EB%A6%AC%EC%99%80-%EC%A4%91%EC%9A%94%ED%95%9C-%EC%9B%90%EC%B9%99]
이미지 출처

  • DOM의 요소들은 node를 상속받기 때문에 textContent, childNodes, firstChild, lastChild, parentNode, cloeNode, appendChild 등 node의 기능을 전부 갖고 있다.
  • node는 eventTarget 을 상속받기 때문에 이벤트 관련된 메소드를 사용할 수 있다.
  • Event Target method : addEventListner, removeEventListner, dispatchEvent
  • 각 요소마다 고유의 기능도 있다. ex) a - href,target, img - src
  • CSS는 CSS Object Model을 가짐. 트리형식. 브라우저는 DOM+CSSOM을 이용해 화면을 그림
  • BOM : Browser Object Model - 브라우저 자체를 다루는 api. ex)alert, setTimeout, ..

DOM tree


[https://ko.wikipedia.org/wiki/%EB%AC%B8%EC%84%9C\_%EA%B0%9D%EC%B2%B4\_%EB%AA%A8%EB%8D%B8]
이미지 출처

node들의 트리 구조로 이루어져있다.

Virtual DOM

Virtual DOM (VDOM)은 UI의 이상적인 또는 “가상”적인 표현을 메모리에 저장하고 ReactDOM과 같은 라이브러리에 의해 “실제” DOM과 동기화하는 프로그래밍 개념

  • Virtual DOM은 SPA에서 사용하면 DOM의 구조만 간결히 흉내낸 자바스크립트 객체
  • 실제 DOM을 조작하는 것은 무겁기 때문에 가벼운 가상DOM을 만들어, 실ㅈ ㅔDOM과 비교해 바뀐 부분만 실제 DOM을 조작해 반영.
  • 런타임에서 작동함. 브라우저가 js 파일(라이브러리)을 받아서 DOM을 그리고 최소한의 변경으로 구현하는 방법을 찾는 방식

Svelte

  • 가상 DOM 없이 조작을 하기 때문에 리액트, 뷰보다는 빠름
  • Svelte은 컴파일러이기 때문에 런타임 환경이 아닌 배포되기 전에 위의 과정이 일어남

📑 reference

'Javascript' 카테고리의 다른 글

실행 컨텍스트  (0) 2021.11.28
자바스크립트 런타임환경  (0) 2021.09.11
이벤트  (0) 2021.08.28
CRP(Critical render path, 브라우저 렌더링 순서)  (0) 2021.08.21
Web API  (0) 2021.08.12

타입스크립트의 모듈 시스템

타입스크립트 모듈은 전역 변수와 구분되는 자체 유효 범위를 가지며 export import와 같은 키워드를 사용하지 않으면 다른 파일에서 접근할 수 없다.

// app.ts
import{Todo} from './types'

var item:Todo = {
    title:'할 일 1',
    checked:false
}
export interface Todo{
    title:string;
    checked:boolean;
}

📑 referece

'TypeScript' 카테고리의 다른 글

타입추론, 타입단언, 타입가드  (0) 2021.08.01
class와 generic  (0) 2021.08.01
타입스크립트 - 변수와 함수 타입  (0) 2021.07.13
Why Typescript?  (0) 2021.07.12

타입추론

타입스크립트가 코드를 해석해 나가는 동작을 의미한다.

인터페이스와 제네릭을 이용한 타입 추론 방식


제네릭을 선언했을 때, 타입스크립트가 제네릭을 이용해 타입을 추론해 변수에 필요한 속성을 보장해준다.

복잡한 구조에서의 타입 추론 방식

DetailedDropdown에서 value와 tag가 제네릭 타입으로 정의해야 한다.

Best Common Type 추론 방식

Best Common Type은 타입스크립트가 타입을 해석하는 알고리즘
모든 타입을 union으로 묶어감

타입단언

Typescript의 타입 추론 기능은 매우 강력하지만 어쩔 수 없는 한계가 존재한다. 타입 단언은 타입스크립트 컴파일러가 실제 런타임에 존대할 변수의 타입과 다르게 추론하거나 너무 보수적으로 추론하는 경우에 프로그래머가 수동으로 컴파일러한테 특정 변수 타입에 대해 힌트를 주는 것이다. as 키워드를 사용한다.

타입 캐스팅과의 차이는 타입 캐스팅은 컴파일타임과 런타임에서 모두 타입을 변경시키지만 타입 단언은 오직 컴파일타임에서만 타입을 변화시킨다는 것이다.

아래의 예시에서 b=aa라고 했을 때 b를 any로 추론한다.

var aa;
aa = 20; // number로 할당
aa = 'a' // string으로 재할당

하지만 aa에 최종적으로 string을 할당했기 때문에 aa의 타입은 string이므로, as로 string 타입임을 단언하면 b를 string으로 추론을 하게된다.

ex] DOM API 조작에서 타입단언의 예

<div id="app">hi</div>

DOM API의 타입도 일반적으로 제공을 하지만 실제로는 DOM API를 사용하는 시점에 해당 element가 있다는 것을 보장하지 않는다. 사실상 null와 HTMLDivElement 타입을 갖게 되는 것이다.
따라서 아래와 같은 패턴으로 사용한다.

var div = document.querySelector('div') 


if(div){
  div.innerText;
}

타입 단언을 해주면 null 타입을 갖지 않게 되므로 아래와 같이 사용할 수 있다.

var div = document.querySelector('div') as HTMLDivElement;
div.innerHtext;

타입가드

타입가드는 타입 단언을 좀 더 깔끔하게 할 수 있도록 도와준다. 타입 가드는 런타임에서의 타입 체크를 컴파일러에게 알려주는 기능이다. is키워드를 사용한다.

interface Developerr{
    name:string;
    skill:string;
}

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

function introduce() : Developerr|Personn { 
    return {name:'Tony', age:33, skill:'Iron Making'}
}

공통속성아 아닌 타입을 사용하기 위해서 타입단언을 이용해 아래와 같이 사용하면 가독성이 떨어진다.

if((tonytony as Developerr).skill){
    var skill = (tonytony as Developerr)
    console.log(skill)
}else if ((tony as Person).age){
    var age = (tonytony as Personn)
    console.log(age)
}

isDeveloper라는 타입가드를 정의하면 같은 로직을 아래와 같이 사용할 수 있다.

// 타입가드를 정의
function isDeveloper(target:Developerr|Personn):target is Developerr {
    return (target as Developerr).skill !== undefined;
}

if(isDeveloper(tonytony)){
    console.log(tonytony.skill)
}else{
    console.log(tony.age)
}

타입호환

타입 호환이란 타입스크립트 코드에서 특정 타입이 다른 타입에 잘 맞는지를 의미한다. 타입스크립트는 정의되어 있는 속성의 타입에 따라 호환되는지를 확인한다. 이를 구조적 타입시스템이라고 한다.

sum이 add보다 타입구조적으로 더 넓기때문에 sum은 add와 호환이 안됨

인터페이스 - 클래스의 타입호환

interface Named {
    name: string;
}

class Person {
    name: string;
}

let p: Named;
// 성공, 구조적 타이핑이기 때문입니다.
p = new Person();

함수 - 제네릭의 타입호환


📑 referece

'TypeScript' 카테고리의 다른 글

타입스크립트의 모듈  (0) 2021.08.01
class와 generic  (0) 2021.08.01
타입스크립트 - 변수와 함수 타입  (0) 2021.07.13
Why Typescript?  (0) 2021.07.12

프로토타입

자바스크립트는 객체를 상속하기 위해 프로토타입이라는 방식을 사용한다. 자바스크립트는 프로토타입 기반언어로서 모든 객체들이 메서드와 속성들을 상속 받기 위한 템플릿으로 프로토타입 객체(prototype object)를 갖는다. 프로토타입 객체로 또 다시 상위 프로토타입 객체로부터 메서드와 속성을 상속 받을 수도 있고 그 상위 프로토 타입 객체로 마찬가지다. 이를 프로토타입 체인이라고 부르고 다른 객체에 정의된 메서드와 속성을 한 객체에서 사용할 수 있도록 한다.

상속되는 속성과 메서드들은 각 객체가 아니라 객체의 생성자의 prototype이라는 속성에 정의되어 있다. prototype 속성도 하나의 객체이며 프로토타입 체인을 통해 상속하고자 하는 속성과 메서드를 담아주는 버킷으로 주로 사용된다.

객체를 선언했을 때 사용할 수 있는 메서드는 Object라는 최상위 프로토타입 객체를 갖고 있기 때문이다.

클래스

프로토타입 기반의 상속은 유지되고, 문법만 바뀐 것이다.

class Person{
    // 객체를 만들 때 호출됨
    constructor(name, age){
        this.name = name;
        this.age = age;
        console.log('생성되었음')
    }
}

const inkuk = new Person('사람',30);
function Person(name,age){
    this.name = name;
    this.age = age;
}

var capt = new Person('캡틴',100)
class Developer{
    // 변수의 접근 범위를 지정할 수 있다.
    private name:string;
    public age:number;
    readonly log:string;

    constructor(name:string,age:number){
        this.name = name;
        this.age = age;
    }
}

제네릭(Generics)

한가지 타입보다 여러 가지 타입에서 동작하는 컴포넌트를 생성하는데 사용한다. 타입스트립트에서는 타입을 함수의 파라미터처럼 받을 수 있는 것을 제네릭이라고 한다. 함수를 정의할 때가 아닌 호출하는 시점 에 타입을 정의해 파라미터와 반환값에 대한 정확한 타입 추론이 가능하다. 다양한 타입을 받기위해 같은 기능을 하는 함수를 타입만 다르게 여러번 선언할 필요가 없기 때문에 유지보수, 코드 가독성이 좋아진다.

타입을 정의하지 않으면 any타입

string 타입을 제네릭으로 넣으면 string 타입으로 바뀜

기존문법과 제네릭의 차이점

  • any 타입과 달리 제네릭으로 타입을 정의하면 제네릭 타입에 해당하는 메서드 자동완성 기능을 사용할 수 있다.
  • union 타입으로 선언하면 input 값에 대한 에러는 없지만 공통속성에 대한 메서드만 사용할 수 있다.
  • 제네릭을 이용해서 타입을 선언하면 자동완성 등 타입선언의 이점을 누릴 수 있다.

인터페이스에 제네릭 선언하기

아래의 예제에서 Email타입과 ProductNumber 타입은 value와 selected 프로퍼티를 갖지만 value의 타입이 달라 두 개의 타입으로 선언했다. 이 경우 interface에 제네릭을 선언해 이용할 수 있다.

interface Email{value:string; selected:boolean}

const emails:Email[] = [
  { value: 'naver.com', selected: true },
  { value: 'gmail.com', selected: false },
  { value: 'hanmail.net', selected: false },
];

interface ProductNumber
{value:number;selected:boolean}

const numberOfProducts:ProductNumber[] = [
  { value: 1, selected: true },
  { value: 2, selected: false },
  { value: 3, selected: false },
];
interface Dropdown<T>{
  value:T;
  selected:boolean;
}

const obj:Dropdown<string> = {
  value:'abc',
  selected:false
}

제네릭의 타입 제한

  1. 정의된 타입
  2. key of 이용하기
    // 타입제한1. 제네릭으로 받은 타입을 배열로 사용할거야
    function logTextLength(text:T[]):T[]{
    // 배열 메서드를 사용할 수 있음
    console.log(text.length);
    return text;
    }

// 타입제한2. 정의된 타입 이용하기
interface LengthType{
length:number;

}

function logTextLength2(text:T):T{
text.length;
return text;
}

// 타입제한3. key of - 선언한 타입 중 하나를
interface ShopingItem{
name:string;
price:number;
stock:number;
}

function getShoppingItemOption(itemOption:T):T{
return itemOption;
}


📑 referece
-MDN - Object prototypes

'TypeScript' 카테고리의 다른 글

타입스크립트의 모듈  (0) 2021.08.01
타입추론, 타입단언, 타입가드  (0) 2021.08.01
타입스크립트 - 변수와 함수 타입  (0) 2021.07.13
Why Typescript?  (0) 2021.07.12

기본타입

  • 문자열
  • 숫자
  • 배열
  • 튜플
  • 객체
  • boolean
  • null, undefiled
  • | 연산자
// 문자열
const str: string = 'hello';

// 숫자
const num: number = 10;

// 배열
const arr: Array<number> = [1, 2, 3];
const heroes: Array<string> = ['Capt', 'tor'];
const items: number[] = [1, 2, 3];

// 튜플
const tuple: [string, number] = ['haha', 1];

// 객체
const obj: object = {};

const person: { name: string; age: number } = {
  name: 'thor',
  age: 1000
};

// boolean
const show: boolean = true;

// undefined, null
let mightBeUndefined : string|undefined = undefined;
let nullableNumber : number|null = null;

// | 연산자
let color:'red'|'orange'|'yellow' = 'red';
color = 'yellow'; //color = 'green'; 

함수타입

  • 함수 타입은 파라미터와 반환값에 타입을 정의한다.

  • return type이 없으면 void 함수

  • function sum(a: number, b: number):number { return a + b; } sum(10, 20);

  • 파라미터를 제한하는 특성으로 파라미터의 갯수나 타입을 체크한다

  • optional parameter : 파라미터에?를 붙이면 파라미터가 없어도 에러가 나지 않는다.

인터페이스

interface는 클래스 또는 객체 를 위한 타입을 지정 할 때 사용하는 문법

  • 변수를 정의
  • 함수의 인자 정의
  • 함수 구조를 정의
  • 인덱싱 방식을 정의
  • 인터페이스 딕셔너리 패턴
  • 인터페이스 확장(상속)

변수정의 및 함수의 인자를 정의하는 인터페이스

// 인터페이스 정의
interface User{
    age:number;
    name:string;
}

// 변수 정의
var saram1:User = {
    age:33,
    name:'세호'
}

// 함수의 인자 정의
function getUser(user:User){
    console.log(user);
}

getUser(saram1)

함수의 스펙(구조)에 인터페이스 활용

interface SumFunction{
    (a:number,b:number):number;
}

let sum: SumFunction;
sum = function(a,b,){
    return a+b
}

인덱싱 방식을 정의하는 인터페이스

interface StringArray{
    [index:number]:string;
}

const arr:StringArray = ['a','b','c']

// indexing
arr[0] = 'd'

인터페이스 딕셔너리 패턴

interface StringRegexDictionary{
    [key:string]:RegExp // 정규표현식
}

const obj:StringRegexDictionary = {
    sth:/abc/, // 통과
    sss:'abc', // 에러
}

인터페이스 확장

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

interface Developer extends Person{    
    language:string;
}

const me:Developer = {
    name:'Gisele',
    age:30,
    language:'javascript'
}

타입별칭(Type Aliases)

  • 타입 별칭은 특정 타입이나 인터페이스를 참조할 수 있는 타입 변수를 의미한다.
  • string,number와 같은 간단한 타입 뿐 아니라 interface 레벨의 복잡한 타입에도 별칭을 부여할 수 있다.
  • 타입 별칭에 제네릭도 사용할 수 있다.
  • 타입 별칭은 새로운 타입 값을 생성하는 것이 아니라 정의한 타입에 대해 나중에 쉽게 참고할 수 있게 이름을 부여하는 것과 같다.
type Person = {
    name:string;
    age:number;
}

const seho:Person={
    name:'세호',
    age:30
}

Alias와 Interface의 차이점

Inferace Type
확장 🌷 가능 불가능
재할당 가능 불가능
목적 구현 데이터를 담기

좋은 소프트웨어는 확장이 용이해야하기 때문에 type보다는 interface로 선언해서 사용하는 것을 추천

연산자를 이용한 타입정의

Union Type(|)

하나 이상의 타입을 쓰고 싶을 때, | 연산자를 이용해 여러 연산자를 여러 개 연결할 수 있다. (or의 의미)

function logMessage(value:string| number){ // union type
    if(typeof value==='number'){     
        console.log(value.toLocaleString())
    }

    if(typeof value==='string'){
        console.log(value.toLowerCase())
    }

    throw new TypeError('value must be string or number')
}
  • 타입 추론이 되기 때문에 아래와 같이 해당 타입에 대한 자동완성 기능을 이용할 수 있다.

  • interface 두 개를 합쳤을 때, 공통된 속성에만 접근할 수 있다.

Intersection Type(&)

여러 타입을 모두 만족하는 하나의 타이블 의미한다.

Union type와 Intersection type의 차이

  • union type으로 선언했을 경우, 그 중 하나에 해당하는 타입으로 사용이 가능하지만, intersection type의 경우 모든 항목을 만족하는 타입을 사용해야 한다.

Enums

이넘은 특정 값들의 집합을 의미하는 자료형이다.
이넘을 선언하고 별도의 값을 지정하지 않으면 숫자형 이넘으로 0부터 1씩 증가한다.

// 숫자형 이넘
enum Shoes{
    Nike, //0
    Adias, //1
    NewBalance//2
}

const myShoes = Shoes.Nike
console.log(myShoes); // 0

// 문자형 이넘
enum Shoess{
    Nike = '나이키',
    Adias = '아디다스',
    NewBalance = '뉴발란스'
}

const myShoes = Shoess.Nike
console.log(myShoes); //나이키

활용

위와 같이 string type으로 타입을 정의할 경우 yes,no가 아닌 다른 값도 들어와서 예외처리를 할 수 없다. Enum type을 사용하면 지정한 값이 아닌 다른 값에 대해 미리 에러가 발생한다.


📑 referece

'TypeScript' 카테고리의 다른 글

타입스크립트의 모듈  (0) 2021.08.01
타입추론, 타입단언, 타입가드  (0) 2021.08.01
class와 generic  (0) 2021.08.01
Why Typescript?  (0) 2021.07.12

+ Recent posts