[Typescript] 기초 다지기 4. 인터페이스

dee·2022년 10월 7일
4

typescript

목록 보기
4/5
post-thumbnail

🤔 왜 자바스크립트에 없을까?

이번에 다룰 인터페이스는 자바스크립트 환경에서는 다뤄지지 않는다.
이는 인터페이스가 타입 체크가 목적이기 때문이다. 타입 체크는 컴파일시 타입이 결정되는 정적 타입 언어에서 가능하다. 그렇기에 동적 타입 언어인 자바스크립트에서는 인터페이스가 없다. 처음 접하는 개념인만큼 정리하면서 정리해보자.

동적 타입 언어 vs 정적 타입 언어

동적 타입 언어정적 타입 언어
정의   런타임시 타입이 결정컴파일시 타입이 결정
장점런타임까지 타입 결정을 끌고 갈 수 있어 언어가 유연  문제점 초기 발견이 가능    
속도 빠름
단점타입 결정이 런타임에 되어
예상치 못한 타입이 들어와서 오류 발생 가능성
타입 지정의 번거로움

기초 4. 인터페이스

  • 타입 검사가 목적.
  • 변수, 함수, 클래스에 사용 가능.
  • 구조적 패턴은 사용자 정의 타입(Type Alias)과 비슷해보이자만 인터페이스는 병합 가능.
  • 인터페이스에 선언된 프로퍼티와 메소드는 필수적으로 구현되어야 함.
  • 클래스와 유사하지만 직접 인스턴스 생성 불가하며 클래스와 달리 일반 메소드는 가질 수 없음.
  • 선언된 프로퍼티와 메소드는 모두 추상. 따라서 abstract 키워드 사용 안 함.
interface Bird {
	name: string;
    age: number;
}

// 변수에 타입 설정.
let bird: Bird;
bird = { name: 'pigeon', age: 5 };

// 함수 매개변수에 타입 설정.
function updateBird(newbird: Bird){
	bird = newbird;
}

updateBird({ name: 'parrot', age: 8 });

  • 선택적 프로퍼티(Optional property)
    - 프로퍼티 뒤에 ?를 붙여 선택적으로 프로퍼티를 생성하게끔 함. (에러 방지)
  • 읽기 속성 (readonly)
// color 속성은 선택적 프로퍼티.
// style 속성은 읽기 속성.
interface Hair {
	color?: string;
    readonly style: string;
}

let hair: Hair;
hair = {style: 'design perm'}

// 읽기 속성에 할당하여 오류 발생
hair.style = 'dyeing' // Error : Cannot assign to 'style' because it is a read-only property.(2540)
  • 함수 타입
    - 매개변수 리스트와 반환값 타입 설정.
    - 함수 인터페이스를 구현하는 함수는 인터페이스 준수 필요.
    - 임의로 변경 시 오류.
// Rectangle interface
interface Rectangle {
	(width: number, height: number) : number;
}

// Rectangle 타입 선언 : 매개변수 및 반환값 설정 하지 않아도 오류 발생 안 함.
const rect: Rectangle = (width, height) => {
	return width * height;
}

console.log(rect(3, 4)) // 12
  • 클래스
    - implements 뒤에 인터페이스 선언.
    - 인터페이스에 지정된 프로퍼티와 메소드 구현 필수.
interface Shape {
  shape: string;
  width: number;
  height: number;
  calcArea(): number;
}

// Shape에 선언된 프로퍼티와 메소드 구현.
class Rectangle implements Shape {
  public shape = 'rectangle';
  constructor(public width: number, public height: number){};
  
  calcArea(){
    return this.width * this.height;
  }
}

const rect = new Rectangle(10, 20);
console.log(rect.calcArea()); // 200

인터페이스 상속

extends 키워드를 사용하여 인터페이스나 클래스 상속 가능.
클래스를 상속받을때 모든 멤버가 상속되지만 구현은 상속되지 않는다.

interface Shape {
  shape: string; 
}

// extends로 Shape 상속.
interface Area extends Shape {
  width: number;
  height: number;
  calcArea(): number;
}

// 인터페이스 Area와 Shape에 선언된 프로퍼티와 메소드를 정의해야함.
let area: Area = {
  shape: 'rect', 
  width: 100, 
  height: 10, 
  calcArea(){
    return this.width * this.height;
  } 
};

console.log(area.calcArea()); // 1000

클래스와 객체 리터럴 차이

  • 클래스
    인터페이스 요구사항을 준수했을 때 새로운 속성이나 메소드가 추가되어도 오류 발생하지 않음.
interface Shape {
	shape: string;
	width: number;
	height: number;
}

class Rectangle implements Shape {
 	shape = 'rect';
	constructor(public width: number, public height: number){}
	
	// 인터페이스에 정의되지 않은 메소드.
	calcArea():number {
		return this.width * this.height;
	}
}
  • 객체 리터럴
    타입 체크가 엄밀하여 요구사항만을 준수하여 구현 필요.
    정의되지 않은 동적 타입이 할당되는 것을 타입스크립트는 오류로 체크하기 때문.
    이 오류를 막기 위해서는 해결책은 아래와 같다.
  1. ts.config.json: noImlictAny를 false로 설정. (좋지 않은 방법)
  2. 객체 변수 as 인터페이스 이름.
interface Shape {
	shape?: string;
}

function setShape(s: Shape){
  console.log(s)
}

// 단, 인터페이스 프로퍼티가 선택적 프로퍼티여야 한다.
let rect = { shapeName: 'rect'};
setShape(rect as Shape);
  1. 인터페이스에서 인덱스 시그니처 속성 선언
// []로 동적으로 추가될 프로퍼티 선언. 
// 타입은 any로 설정.
interface Shape {
	shape: string;
  	[prop: string]: any;
}


🍑 오늘의 공부일기

오늘은 공부하면서 인터페이스보다 정적과 동적 타입의 언어에 대한 개념이 더 기억에 남았다. 항상 새로운 개념이 재밌어서 기억에 남았지만 원초적인 개념(?)이 머릿 속에 좀 더 와닿게 이해가 되서 기억에 잘 남았다. 왜 자바스크립트가 느슨한 언어라는 말이 있는지, 타입 체커를 정적 타입에서 가능한 지에 대한 의문들을 한 번에 풀어주는 열쇠가 되었다.
그리고 덕 타이핑을 공부하면서 자바스크립트를 배웠을 때가 생각이 났다. 자바스크립트 배울 초기에 객체나 배열 비교시 보이는 구조가 아니라 참조 값으로 하는 부분이 신기했는데 덕 타이핑이 처음 객체 비교에 대한 생각대로 움직이고 있어서 이 개념을 바탕으로 인터페이스를 복습하면서 익혀야겠다.


참고 자료
https://yamoo9.gitbook.io/typescript/types/array
https://poiemaweb.com/typescript-interface
https://joshua1988.github.io/ts/guide/interfaces.html#%EC%9D%B8%ED%84%B0%ED%8E%98%EC%9D%B4%EC%8A%A4

profile
웹 프론트엔드 개발자

1개의 댓글

comment-user-thumbnail
2022년 10월 7일

최고의 정리!

답글 달기