본문 바로가기

회고록(TIL&WIL)

TIL 2022.10.26 Typescript 기본2

Basic한 typescript 사용 하여 html 과 연결하여 조작 변경

tsconfig.json - strictNullChecks 코드 추가 외에도 여러가지 모드가 있는데 전체적으로 걸려면

strict 만 하면 전체적으로 모드가 켜지긴함 우선 Null 체크만 하기 위해 하나의 모드만 켜는게 일반적

{   
  "compilerOptions" : {     
    "target": "es5",     
    "module": "commonjs",  
    "strictNullChecks": true
  } 
}

 

typescript 에서는 기존 자바스크립트 처럼 document.querySeletor() 또는 getElementById() 를 사용하는데

그냥 사용하게 되면은 type이 Element or null 인것으로 파악이 되기 때문에 사용할 수 없다

(잘못 파악하는 경우 null 로 나와야되기떄문에 union 타입이 되는 것)

 

그래서! typescript 에서는 타입을 하나로 narrowing 작업을 해줘야한다. 타입을 확실하게 정해줘야한다.

방법 1 - null 인지 아닌지 판별하면 ok

if (제목 != null) {
	제목.innerHTML = "반가워요"
}

방법 2 - instanceof 연산자 사용 (가장 많이 사용됨) (오브젝트가 해당 클래스의 인스턴스인가? 판별)

if (제목 instanceof Element) {
	제목.innerHTML = "반가워요"
}

방법3 -  오브젝트에 ?. 을 붙여서 사용 (해당 오브젝트가 innerHTML이 있는지 없는지 판별)

if(제목?.innerHTML){
	제목.innerHTML = "반가워요"
}

방법4 - typeof 함수를 이용해서 타입 여부 파악 ( 기본적으로 "string", "number" 같은 기본형에 사용)

let 글자: string  = '안녕하세요'

if(typeof 제목 === "string") {
	글자 = '반가워요'
}

주의 ! ) a 태그의 href 내용을 변경 하려고 할 때 instanceof 를 이용해서 Element 의 인스턴스인지 판별하면 오류가 나는데

Element 는 최상위 클래스로 각각의 오브젝트의 모든 메서드를 담고 있는게 아니기 때문에 이를 상속 받는 여러 클래스들에서는 href, css, class 같은 메서드를 정의 해둔 클래스의 인스턴스인지 아닌지 판별해야 narrowing 이 가능하다.

let 링크 = document.querySelector('.link')
if (링크 instanceof HTMLAnchorElement){
    링크.href = 'https://kakao.com'
}

다양한 Element의 클래스들

대표적으로

HTMLAnchorElement -> a 태그

HTMLHeadingElement -> h1 태그

HTMLButtonElement -> button 태그

처럼 태그마다 정해져 있음

 

 

 

 

 

 

 

typescript 에서 eventListener 부착하는 법 ?. 만 사용해도 narrowing이 된다. 값이 없으면 undefined 를 return

let 버튼 = document.querySelector('#button')
버튼?.addEventListener('click', function(){

})

interface

object를 타입을 미리 설계하고 그 object안에 변수들의 타입을 미리 정해둘 수 있다.

type Score = "A" | "B" | "C"

interface User {
    name: string;
    age: number;
    gender?: string;  // 옵션으로설정(있어도그만 없어도그만)
    readonly birth: number;  // 읽기전용
    //[grade: number] : string; // key: number = value: stinrg
    [grade: number] : Score; // key: number = value: stinrg
}

let user : User = {
    name : '홍길동',
    age : 30,
    birth : 1990,
    1: "A",
    2: "B",
    // 3: "F", 오류발생!
}

user.age = 10
user.gender = 'male'
//user.birth = 1999  오류 발생!

함수의 형태 및 파라미터 또한 지정할 수 있다.

interface Func1{
	(num1: number, num2:number) : number;
	// (파라미터 : 타입) : return타입
}

const add : Func1 = function(x, y) {
	return x + y
}
interface IsAdult {
    (age:number):boolean;
}

const people : IsAdult = (age)=>{
    return age > 19
}

 

클래스도 미리 정의해둘 수 있다. class 정의 시 만들어둔 interface를 implements 해와서 정의하고 extends 를 이용해서 확장 할 수 도 있다 extends 는 여러개의 interface를 받아 확장 할 수있다.

interface Car {
    color: string;
    wheels: number;
    start(): void;
}

class Bmw implements Car {
    color;
    wheels = 4;
    constructor (c:string){
        this.color = c
    }
    start(){
        console.log('gogogo')
    }
}
const newCar = new Bmw('green')


interface Benz extends Car {
	door: number;
	stop(): void;
}

class benz : Benz = {
	door: 5
	stop(){
	console.log('skrrrr')
	}
	color: 'blue';
	wheels: 4
	start(){
	    console.log('gogogo')
    }    
}