본문 바로가기
tsc

캐스팅 || 업캐스팅 || 다운캐스팅 || 타입스크립트 에서의 타입캐스팅

by Box 2022. 1. 20.
728x90

캐스팅

캐스팅이란 타입을 변환하는 것을 말하며 형변환이라고도 한다.

상속 관계에 있는 부모와 자식 클래스 간에는 서로 간의 형변환이 가능하다.

 

업캐스팅(Upcasting)

업캐스팅이란 자식 클래스의 객체가 부모 클래스 타입으로 형변환 되는 것을 말한다.

아래 코드에서 부모 클래스는 Person, 자식 클래스는 Student이다.

아래 코드에서 Person p = s; 부분이 업캐스팅한 부분이다.

p가 Student 객체를 가리키지만, p는 Person 타입이기 때문에 Person 클래스의 멤버에만 접근이 가능하다.

그렇기 때문에 p.check에서 컴파일 타임 에러가 발생한다.

class Person{
	String name;
	Person(String name){
		this.name = name;
	}
}

class Student extends Person{
	String check;
	Student(String name){
		super(name);
	}
}

public class Main{
	public static void main(String[] args){
		Student s = new Student("홍길동");
		Person p = s;	// 업캐스팅
		p.name = "이름이다.";

		p.check = "컴파일 에러 발생";	// 컴파일 에러 발생
	}
}

 

다운캐스팅(Downcasting)

업캐스팅과 반대로 캐스팅 하는 것을 다운캐스팅이라고 한다.

업캐스팅된 것을 다시 원상태로 돌리는 것을 말한다.

하위 클래스로의 다운캐스팅을 할때는 타입을 명시적으로 지정해줘야한다는 특징이 있다.

아래 코드를 보면 Student s = (Student)p; 라고 나오는데 이 부분이 바로 다운캐스팅이다.

class Person{
	String name;
	Person(String name){
		this.name = name;
	}
}

class Student extends Person{
	String check;
	Student(String name){
		super(name);
	}
}

public class Main{
	public static void main(String[] args){
		Person p = new Student("홍길동");
        
		Student s = (Student)p;	// 다운캐스팅
		s.name = "김유신";
		s.check = "check!";
	}
}

 

TSC 타입스크립트 [ Type Assertions] (타입 표명)

 

타입 표명 vs. 캐스팅(Casting)

 

타입 표명을 "타입 캐스팅(type casting)"이라 부르지 않는 이유는 일반적으로 캐스팅이란 말은 실행 시간에 어떤 동작이 일어날 것임을 내포하기 때문입니다.

하지만 "타입 표명(type assertions)"은 순수하게 컴파일 시간 구성물이고 당신의 코드가 어떤 식으로 분석되길 원하는지 컴파일러에게 힌트를 제공하는 수단입니다.

 

1. 타입 어센션을 하는 방법

  • <foo> : 꺽쇠를 변수 앞에 작성
  • as foo : 변수 뒤에 붙임

* 용례

var foo:any;
var bar = <string>foo // 이제 bar의 타입은 string입니다.
var bar2 = foo as Boolean // 이제 bar의 타입은 Boolean입니다.

 

 

2. 이중 표명

 

개발자가 스스로 타입을 단언하는 것은 많은 위험성을 내포하고 있다. 그러나, 타입스크립트가 추론한 타입보다 더 좁은 타입을 선언해주는 것은 아주 정당한 사용 사례로 평가 받고 있다. 간단한 예시를 확인해보자.

function handler (event: Event) {
    let mouseEvent = event as MouseEvent; 
    /* params의 타입인 event를 MouseEvent라는 더 좁은 타입으로 선언하여 
    mouseEvent라는 새로운 변수에 할당 */
}

// 넓은 타입으로 구성된 배열을 순회할때도
// 각 요소들을 좁은 타입으로 재선언할 수 있다. (물론 두 타입이 충분히 겹쳐야한다)

type SampleType = {
	id: string;
    userData:unknown;
    }
    
type DetailedSampleType ={
	id:string;
    userData:{
    	nickname:string,
    	job: string
       }
 	}
    
 const sampleArr:Array<SampleType> = getSampleTypeArray()
 
 sampleArr.forEach((elem)=>{
 	// 이시점에서는 elem은 SampleType이지만,
    const newElem = elem as DetailedSampleType
    // 이 newElem은 DetailedSampleType이 된다
    
    console.log(elem.userData.nickname) // userData가 unknown 타입이라 접근 자체가 불가
    console.log(newElem.userData.nickname) // newElem은 DeatiledSampleType이라 접근 가능

 

3. 타입이 Nested 된 경우, 대괄호 접근법으로 접근 가능

 

어떤 변수에 타입을 지정해줘야하는데, 우연히도 그 타입이 Object 안에 Nest된 타입인 경우, 대괄호 접근법으로 해당 타입을 가져올 수 있다. 

 

type Sample = {
	id:string;
    name:string;
    target:{nickname:string, age: number}
}


const age = mikeAge as Sample['target']['age'] // age는 이제 number 타입입니다

 

'tsc' 카테고리의 다른 글

타입스크리트 / type 과 interface 의 차이  (0) 2022.02.11
타입스크립트 / generic  (0) 2022.02.02