-
dom 조작 시 typescript 사용법.typescript 2022. 1. 18. 00:12
리액트나 뷰같은 프레임워크를 쓰지않고
순수 자바스크립트(타입스크립트)로 dom 조작을 하려면 셀렉터로 element를 찾아야하는데,
이 때 셀렉터에 인자로 넣은 id나 class 이름 또는 태그 이름이 없다면
해당 셀렉터가 null를 반환하는것은 모두 알고 있을것이다.
타입스크립트에서는 이 셀렉터가 null를 반환할 가능성이 있다면
이를 체크하게할 수 있다.
바로 패키지 내 tsconfig.json을 수정해준다.
저 strictNullChecks를 true로 설정해주면
앞으로 셀렉터로 요소들을 찾을 때 꼭 narrowing이나 assertion을 거쳐야만
경고가 없어지도록 강제할 수 있다.
저렇게 설정하고 셀렉터로 요소를 찾아서 변수에 할당해보자.
일반적으로 저렇게 에러가나는데,
그 이유는 narrowing같은 설정이 없다면 해당 '제목'이라는 변수는
셀렉터가 요소를 찾는다면 html 요소가 할당될것이고
찾지못한다면 null이 할당될것이기에
셀렉터로 찾은 요소는 저렇게 Element | null이라는 union 타입을 기본적으로 갖는다.
그래서 저 에러를 없애는 narrowing 방식들을 알아보자.
1)
!= null 도 narrowing 방식의 일종이다.
2)
다음은 가장 자주 쓰인다는 instanceof 함수를 사용한 narrowing 방식이다.
instanceof는 자바에서도 본 함수인데,
해당 요소가 다음의 클래스나 인터페이스를 상속받은 자료형인지 확인하는 메소드이다.
3)
물론 assertion도 가능하지만 타입을 사기치는 방법이니
코드의 작성과 흐름을 더욱 명확히 하려는 타입스크립트의 취지와 엇나가기에
권장되는 방법이 아니다.
4(
저렇게 ?를 써주는 방법이 있는데,
정확한 용어는 option chaining이라고한다.
앞 포스트에서 함수의 type alias를 만들 때,
파라미터에 값이 들어올지 아닐지 확실하지않으면 (a: string, b?: number) 이렇게 지정해준다고 했다.
저러면 파라미터 b의 타입은 number | undefined 이렇게 union 타입이 되는것이다.
위 예시도 마찬가지로 '제목'이라는 변수의 타입은 ?를 붙여주면
Element | null | undefined 이렇게 undefined가 추가되는 union 타입으로 변화한다.
그리고 '제목' 요소를 찾을 수 없어 null이 할당된다면
null이 아닌 undefined가 할당되도록한다.
결국 null이 아닐 시 if 문을 처리하라는 명령으로써 narrowing으로 처리되는것이다.
5)
아니면 tsconfing에서 strictNullChecks를 false로 바꿔줘도된다.
여기서 추가로 instanceof Element로 narrowing을 하는 경우를 좀 더 살펴볼 필요가 있는데,
만약
이런 코드를 작성할 경우 에러가난다.
왜냐하면 '링크'라는 이름의 HTML요소 객체에서 href라는 프로퍼티가 없기때문이다.
즉 '링크'는 Element라는 클래스의 자식 객체이지만 Element에는 href라는 속성이 없어서
if문을 수행할 수 없다.
그 이유는,
Element가 HTML요소(HTMLElement)의 최상위 클래스이기때문이다.
Element에는 innerHTML등의 최소한의 속성을 제외하고는
별다른 속성들이 구현되어있지않다.
따라서 instanceof에 href라는 속성을 가진 클래스를 넣어주어야한다.
자동완성 기능으로 Element를 상속받는 수 많은 자식 HTML클래스들을 확인할 수 있는데,
변경해주고자하는 속성이있는 클래스를 선택해주면된다.
href 속성이 있는 클래스는
이런 클래스이다.
역시 img 태그의 src를 조작하고자한다면
이런식으로 narrowing을 거치면된다.
HTMLImageElement 클래스에는 src라는 속성이 있기때문에
해당 narrowing이 가능한것이다.
'typescript' 카테고리의 다른 글
타입스크립트의 interface란. (0) 2022.01.18 클래스에 타입을 지정해보자. (0) 2022.01.18 함수와 메소드에 type alias 붙이기. (0) 2022.01.17 literal types로 타입 지정해보자. (0) 2022.01.17 type alias란. (0) 2022.01.17