타입스크립트 인터페이스

c_yj·2022년 10월 7일
0

TypeScript

목록 보기
3/7
post-thumbnail

인터페이스란?

인터페이스는 상호 간에 정의한 약속 혹은 규칙을 의미합니다. 타입스크립트에서의 인터페이스는 보통 다음과 같은 범주에 대해 약속을 정의할 수 있습니다.

간단한 예제로 보자

let person = { name: 'CYJ', age: 18 };

function personAge(obj: { age: number }) {
  console.log(obj.age); // 18
}
personAge(person); 

personAge() 함수에서 받는 인자의 형태는 age를 속성으로 갖는 객체입니다. 이렇게 인자를 받을 때 단순한 타입 뿐만 아니라 객체의 속성 타입까지 정의할 수 있죠.

여기에 인터페이스를 적용해보자

interface personAge {
  age: number;
}

function personAge(obj: personAge) {
  console.log(obj.age);
}
let person = { name: 'CYJ', age: 18 };
personAge(person);

인터페이스를 인자로 받아 사용할 때 항상 인터페이스의 속성 갯수와 인자로 받는 객체의 속성 갯수를 일치시키지 않아도 된다. 다시 말해, 인터페이스에 정의된 속성, 타입의 조건만 만족한다면 객체의 속성 갯수가 더 많아도 상관 없다는 의미입니다. 또한, 인터페이스에 선언된 속성 순서를 지키지 않아도 됩니다.

옵션 속성

인터페이스를 사용할 때 인터페이스에 정의되어 있는 속성을 모두 다 꼭 사용하지 않아도 된다!!

interface 인터페이스_이름 {
  속성?: 타입;
}

이처럼 속성의 끝에 ?를 붙입니다.

interface person {
  name: string;
  age?: number;  
}

let korean = {
  name: 'CYJ'
};

function allPerson(korean: person) {
  console.log(korean.name); // Saporo
}

allPerson(korean);

선택적 프로퍼티의 이점은 인터페이스에 속하지 않는 프로퍼티의 사용을 방지하면서, 사용 가능한 속성을 기술하는 것입니다.

읽기 전용 속성

읽기 전용 속성은 인터페이스로 객체를 처음 생성할 때만 값을 할당하고 그 이후에는 변경할 수 없는 속성을 의미합니다. 문법은 다음과 같이 readonly 속성을 앞에 붙입니다.

interface CraftBeer {
  readonly brand: string;
}

인터페이스로 객체를 선언하고 나서 수정하려고 하면 아래와 같이 오류가 납니다.

let myBeer: CraftBeer = {
  brand: 'Belgian Monk'
};
myBeer.brand = 'Korean Carpenter'; // error!

읽기 전용 배열

배열을 선언할 때 ReadonlyArray 타입을 사용하면 읽기 전용 배열을 생성할 수 있다.

let arr: ReadonlyArray<number> = [1,2,3];
arr.splice(0,1); // error
arr.push(4); // error
arr[0] = 100; // error

객체 선언과 관련된 타입 체킹

타입스크립트는 인터페이스를 이용하여 객체를 선언할 때 좀 더 엄밀한 속성 검사를 진행합니다.

interface CraftBeer {
  brand?: string;
}

function brewBeer(beer: CraftBeer) {
  // ..
}
brewBeer({ brandon: 'what' }); // error: Object literal may only specify known properties, but 'brandon' does not exist in type 'CraftBeer'. Did you mean to write 'brand'?

인터페이스에는 brand라고 선언되어 있지만 함수로 넘기는 객체에는 brandon이 선언되어 오류가 발생한다.
이런 타입 추론을 무시하고 싶다면 아래와 같이 선언하자

interface CraftBeer {
  brand?: string;
}


function brewBeer(beer: CraftBeer) {
  // ..
}
let myBeer = { brandon: 'what' }

brewBeer(myBeer as CraftBeer);

그럼에도 불구하고 만약 인터페이스 정의하지 않은 속성들을 추가로 사용하고 싶을 때는 아래와 같은 방법을 사용합니다.

interface CraftBeer {
  brand?: string;
  [propName: string]: any;
}

함수 타입

인터페이스는 함수의 타입을 정의할 때에도 사용할 수 있습니다.

interface login {
  (username: string, password: string): boolean;
}  
let loginUser: login;
loginUser = function(id: string, pw: string) {
  console.log('로그인 했습니다');
  return true;
}  

클래스 타입

클래스가 특정 계약(contract)을 충족시키도록 명시적으로 강제하는 C#과 Java와 같은 언어에서 인터페이스를 사용하는 가장 일반적인 방법은 TypeScript에서도 가능합니다.

interface CraftBeer {
  beerName: string;
  nameBeer(beer: string): void;
}

class myBeer implements CraftBeer {
  beerName: string = 'Baby Guinness';
  nameBeer(b: string) {
    this.beerName = b;
  }
  constructor() {}
}  

하이브리드 타입

자바스크립트의 유연하고 동적인 타입 특성에 따라 인터페이스 역시 여러 가지 타입을 조합하여 만들 수 있습니다. 예를 들어, 다음과 같이 함수 타입이면서 객체 타입을 정의할 수 있는 인터페이스가 있습니다.

interface CraftBeer {
  (beer: string): string;
  brand: string;
  brew(): void;
}

function myBeer(): CraftBeer {
  let my = (function(beer: string) {}) as CraftBeer;
  my.brand = 'Beer Kitchen';
  my.brew = function() {};
  return my;
}

let brewedBeer = myBeer();
brewedBeer('My First Beer');
brewedBeer.brand = 'Pangyo Craft';
brewedBeer.brew();  

출처
https://joshua1988.github.io/ts/guide/interfaces.html#%EC%9D%B8%ED%84%B0%ED%8E%98%EC%9D%B4%EC%8A%A4-%ED%99%95%EC%9E%A5
https://typescript-kr.github.io/pages/interfaces.html

profile
FrontEnd Developer

0개의 댓글