본문 바로가기
개발/TypeScript

잉여타입검사와 덕타이핑

by 안뇽! 2023. 9. 2.
반응형

잉여타입검사

타입이 명시된 변수에 객체 리터럴을 할당할 때

  1. 타입스크립트는 해당 타입의 속성이 있는지
  2. 그 외 속성은 없는지

총 두가지를 검사한다.

 

이는 덕타이핑에 반하는 내용이라 헷갈린다.

잉여타입검사 예시

다음 코드에서는 당연히 Room타입이 할당된 r에서 타입 에러가 나타난다.

Room 타입에 없는 elephant가 나타났기 때문이다.

덕 타이핑을 생각하면 에러가 나타나지 않아야 하지만 일단 넘어가자.


interface Room {
  numDoors: number;
  ceilingHeightFt: number;
}

const r: Room = {
  numDoors: 1,
  ceilingHeightFt: 10,
  elephant: "present", // 개체 리터럴은 알려진 속성만 지정할 수 있으며 'Room' 형식에 'elephat'이(가) 없습니다.ts(2353)
};

r2에 객체리터럴을 할당하지 않고 obj라는 변수를 할당하는 경우를 살펴보자.


interface Room {
  numDoors: number;
  ceilingHeightFt: number;
}

const obj = {
  numDoors: 1,
  ceilingHeightFt: 10,
  elephant: "present",
};
// Room 타입에 없는 elephant가 문제가 되지 않는다.
const r2: Room = obj;

띠용. Room 타입에 없는 elephant가 문제가 되지 않는다.

초과 프로퍼티 검사

덕타이핑검사는 할당 가능 검사에만 작동하고, 잉여타입검사는 이와 별도의 과정이다.

잉여타입검사를 초과 프로퍼티 검사로 생각해도 되는데, 변수에 객체리터럴을 직접 할당할때는 초과 프로퍼티 검사가 작동한다. 

그렇기 때문에 객체 리터럴을 직접 할당했을때 정의되지 않은 타입을 이용하면 에러를 발생시킨다.


interface Room {
  numDoors: number;
  ceilingHeightFt: number;
}

const r: Room = {
  numDoors: 1,
  ceilingHeightFt: 10,
  // elephant는 Room에 정의되지 않은 초과프로퍼티이다.
  elephat: "present", 
};

덕 타이핑

만약 어떤 함수의 매개변수 값이 모두 제대로 주어졌다면, 통과시키는 동작을 덕타이핑이라고 한다.

예를 들면 다음과 같다.

// 덕 타이핑
interface Animal {
  name: string;
}

interface Bird extends Animal {
  fly(): void;
}

const myBird: Bird = {
  name: "Robin",
  fly: () => console.log("flies in the sky"),
};

// myBird의 {name:string}이 Animal을 만족시킨다.
const myAnimal: Animal = myBird;

myBird의 구조가 Animal과 호환되기 때문에 문제없이 작동한다.

 

위의 변수 할당뿐 아니라 매개변수에도 덕 타이핑이 작동한다.

interface Vector2D {
	x:number;
    y:number;
}

function calculateLength(v: Vector2D){
	return Math.sqrt(v.x*v.x + v.y+v.y);
}

interface NamedVector extends Vector2D {
	name:string;
}

const v:NamedVector = {x:3,y:4,name:'Zee'}
calculateLength(v); // 5

NamedVector의 구조가 Vector2D와 호환되기 때문에 calculateLength 호출이 가능하다.

덕 타이핑과 잉여속성체크

덕타이핑은 할당검사에 이루어지는 동작방식이다.

// 덕 타이핑
interface Animal {
  name: string;
}

interface Bird extends Animal {
  fly(): void;
}

const myBird: Bird = {
  name: "Robin",
  fly: () => console.log("flies in the sky"),
};

const myAnimal: Animal = myBird;

잉여속성체크는 할당검사와 별개의 과정으로서, 변수에 객체리터럴을 직접 할당할 때 이루어지고 이때는 덕 타이핑이 동작하지 않는다.

interface Room {
  numDoors: number;
  ceilingHeightFt: number;
}

// 객체 리터럴을 r에 바로 할당하는 경우에는 초과 프로퍼티 검사가 이뤄진다(잉여타입검사)
const r: Room = {
  numDoors: 1,
  ceilingHeightFt: 10,
  // elephant는 Room에 정의되지 않은 속성으로 에러가 난다.
  elephant: "present",
};

const obj = {
  numDoors: 1,
  ceilingHeightFt: 10,
  elephant: "present",
};
// 객체 리터럴을 바로 할당하지 않는 경우에는, 할당검사가 이뤄지는데 이땐 덕 타이핑이 작동한다.
// obj의 속성이 Room과 호환되므로 에러가 발생하지 않는다.
const r2: Room = obj;
반응형