TypeScript

TypeScript 인터페이스

honey.kikiki 2021. 10. 16. 01:36
728x90

타입스크립트 인터페이스

인터페이스란 간단하게 어떠한 두개의 시스템 사이에 상호작용할 수 있게 해주는 조건, 규약 같은 것입니다.

인터페이스는 프로퍼티와 메소드를 가질 수 있다는 점에서 클래스와 유사하나 직접 인스턴스를 생성할 수 없고 모든 메소드는 추상 메소드이다. 단, 추상 클래스의 추상 메소드와 달리 abstract 키워드를 사용하지 않습니다.

1. 인터페이스 사용

타입스크립트에서 인터페이스 사용 예제입니다.

let person = { name: 'kikiki', age: 26};

function logAge(obj: { age: number }) {
	console.log(obj.age); // 26
}

logAge(person); // 26

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

아래는 위의 예제에 인터페이스를 적용한 코드이다.

interface personAge {
  age: number;
}

function logAge(obj: personAge) {
  console.log(obj.age);
}
let person = { name: 'kikiki', age: 26 };
logAge(person);

이제는 logAge()의 인자가 좀 더 명시적으로 바뀌었다. logAge()의 인자는 personAge라는 타입을 가져야한다.

 

1. 인터페이스를 인자로 받아 사용할 때는 항상 인터페이스의 속성 갯수와 인자로 받는 객체의 속성 갯수를 일치시키지 않아도 된다.

2. 인터페이스에 정의된 속성, 타입의 조건만 만족한다면 객체의 속성 갯수가 더 많아도 상관 없고, 인터페이스에 선언된 속성 순서를 지키지 않아도 된다.

 

2. 선택적 프로퍼티

선택적으로 어떠한 옵션을 주어야할 때 선택적 프로퍼티를 이용합니다. 프로퍼티 이름의 끝에 ? 만 넣어주면 됩니다.

interface person {
  key: type;
}

 =>  ex

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


function logAge(obj: personAge) {
    console.log(obj.name);
}

let person = {name:'kikiki'};
logAge(person);

3. 읽기전용 프로퍼티

읽기전용으로 하고싶은 프로퍼티앞에 readonly 만 붙여주면 됩니다.

interface color {
  readonly red: string;
}
let myColor: coloe = {
  red: 'red'
};
myColor.red = 'blue'; // error!

선언하는 시점에만 값을 정의하고  바꿀수 없다. 

변수일 경우엔 const 를 사용하고 프로퍼티일 경우에는 readonly 로 사용하시면 됩니다.

 

추가적으로 배열을 읽기전용으로 하고싶다면 Readonly<type> 으로 선언을 해줍니다.

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

4. 함수 타입

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

interface login {
  (username: string, password: string): boolean;
}

함수의 인자의 타입과 반환 값의 타입을 정합니다.

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

5. 클래스 타입

클래스에서도 인터페이스를 사용할 수 있습니다. implements 라는 키워드를 통해 구현합니다.

interface ClockInterface {
    currentTime: Date;
}
class Clock implements ClockInterface {
}

위의 코드는 에러를 뱉습니다.

TS2420: Class 'Clock' incorrectly implements interface 'ClockInterface'.
 Property 'currentTime' is missing in type 'Clock' but required in type 'ClockInterface'.

implements 라는 키워드가 있다면 해당 인터페이스를 무조건 구현해야합니다.
또한 인터페이스를 구현하는 클래스는 public 만을 사용할 수 있는데 그 이유는 private 로 구현을 하면 인터페이스를 구현했는지 안했는지 모르기 때문입니다.

추가적으로 인터페이스를 구현한 클래스의 타입은 인터페이스가 될 수 있습니다.

interface ClockInterface {
    currentTime: Date;
}
class Clock implements ClockInterface {
    public currentTime: Date;
    // private _currentTime: Date; // Error!
}
const digital: ClockInterface = new Clock();

6. 확장 인터페이스

인터페이스도 클래스처럼 extends 키워드를 통해 확장할 수 있습니다. 인터페이스를 분리함으로써 재사용성이 뛰어나게 됩니다.

interface DOM {
    display: string;
    tag: string;
}
interface TextNode extends DOM {
    text: string;
}
interface InputNode extends DOM {
    type: string;
}

const textNode: TextNode = {
    display: 'inline',
    tag: 'text',
    text: 'heecheolman',
};
const InputNode: InputNode = {
    display: 'inline-block',
    tag: 'input',
    type: 'button',
};

참고

인터페이스 정리

타입스크립트 핸드북