자바에서 인터페이스는 추상 메소드, 상수만을 정의한 클래스를 위주로 다루고, 타입스크립트에서 인터페이스는 객체를 위주로 다룬다.
즉, 요약하자면 타입스크립트에서 인터페이스는 객체의 설계도라 타입을 미리 정의한 틀로 사용할 수 있다.
주로 여러 함수가 특정한 타입을 동일하게 가져야 할 경우, 동일한 타입을 정의하여 인터페이스를 사용할 수 있다.
인터페이스를 통해 선언된 프로퍼티나 메소드의 구현을 강제로 하여 클래스와 함수 등 간의 일관성을 유지할 수 있도록 한다.
타입스크립트에서 인터페이스 아래와 같은 범주에 대해 규칙을 정의할 수 있다.
객체의 스펙(속성과 속성의 타입)
함수의 파라미터
함수의 스펙(파라미터, 반환 타입 등)
배열과 객체를 접근하는 방식
클래스
interface User {
age: number;
name: string;
}
const student: User = {
age: 24,
name: 'guswjd',
};
위와 같이 인터페이스를 정의하고 정의한 인터페이스 자체를 타입으로 줘서 객체를 생성할 수 있다.
옵션 속성
인터페이스를 사용하다 보면, 인터페이스에 정의된 속성을 다 사용하고 싶지 않을 경우가 생긴다.
하지만 정의된 속성을 다 사용하지 않은 경우 아래와 같은 에러가 발생할 것이다.
이때는 옵션 속성을 이용해 인터페이스를 정의하면 된다.
옵션 속성은 속성의 끝에 물음표(?)를 붙여 사용하면 된다.
interface User {
age: number;
name?: string;
}
앞선 예제에서 옵션 속성을 사용한 결과 에러가 발생하지 않는 것을 확인할 수 있을 것이다.
※ 옵션 속성 장점
옵션 속성은 단순히 인터페이스를 사용할 때 속성을 선택적으로 적용할 수 있는 것 뿐만 아니라 인터페이스에 정의되어 있지 않은 속성에 대해 인지시켜 줄 수 있는 장점이 있다.
속성이 정의되지 않았다는 오류를 알려줌오타가 발생하였다는 오류를 알려주고 정의된 속성 이름을 알려줌
읽기 전용 속성
읽기 전용 속성은 인터페이스로 객체를 처음 생성할 때만 값을 할당하고 그 이후에는 변경할 수 없는 속성을 의미한다.
읽기 전용 속성은 속성 이름 앞에 readonly만 붙여 적용하면 된다.
readonly를 사용한 속성은 인터페이스로 객체를 처음 선언하여 값을 대입할 때는 문제가 되지 않는다.
하지만 처음 선언 후 따로 프로퍼티에 접근해 값을 수정하면 오류가 발생한다.
interface User {
age: number;
name: string;
school?: string;
readonly major: string; // 읽기 전용 속성
}
let student: User = {
age: 24,
name: 'guswjd',
major: 'software', // 읽기 전용 속성에 값을 최초로 초기화하여 값을 할당
}
student.major = 'computer'; // 오류 발생
readonly를 보다보면 변수를 선언할 때 사용하는 const와 유사하다고 느낄 것이다.
readonly와 const 모두 초기 값을 선언하면 이 후 값을 수정하지 못하는 점은 같지만, const는 변수에 사용하고 readonly는 프로퍼티에 사용한다는 차이가 있다.
< readonly 활용 >
readonly를 사용하는 경우 모든 속성을 readonly로 지정해야 할 경우가 생길 것이다. 이때는 모든 프로퍼티 각각에 readonly를 붙여주는 방식 보다는 따로 유틸리티나 단언 타입을 활용해 구현하는 방식을 선호한다.
interface User {
readonly age: number;
readonly name: string;
}
위 방식이 readonly를 모든 프로퍼티에 찍어내는 방식이다.
interface User {
age: number;
name: string;
}
let student: Readonly<User> = {
age: 24,
name: 'guswjd',
};
위 방식은 Readonly 유틸리티를 활용한 방식이다. 배열(Array)처럼 따로 Readonly라는 자료형이 있다고 생각하여 사용하는 것이 좋다.
< 읽기 전용 배열 >
배열을 선언할 때 ReadonlyArray<T> 타입을 사용하여 읽기 전용 배열을 생성할 수 있다.
let arr: ReadonlyArray<number> = [1, 2, 3];
arr.push(4); // 오류 발생
arr[1] = 200; // 오류 발생
ReadonlyArray<T>를 사용해 읽기 전용 배열을 선언하면 초기 값을 할당하는 것은 가능하지만, 선언 이후 값을 변경하는 것은 불가능하다.
함수 타입
인터페이스는 함수의 타입으로 사용할 수 있다.( 함수의 스펙(구조)에 인터페이스를 활용할 수 있다.)
함수의 타입으로 인터페이스를 사용할 때는 타입이 선언된 파라미터 리스트와 리턴 타입을 정의한다.
type name = string;
const student: name = 'guswjd';
타입 별칭은 위와 같이 string, number와 같이 간단한 타입 뿐 아니라 인터페이스 정도 구의 복잡한 타입이나 제너릭 등에도 사용할 수 있다.
타입 별칭은 새로운 타입 값을 하나 생성하는 것이 아닌 정의한 타입에 대해 나중에 쉽게 참고할 수 있도록 이름을 부여하는 것이다.
< 인터페이스와 타입 별칭 차이 >
// 타입 별칭 사용한 경우
type User = {
name: string;
age: number;
};
const student: User = {
name: 'guswjd',
age: 24,
}
// 인터페이스 사용한 경우
interface User {
name: string;
age: number;
};
const student: User = {
name: 'guswjd',
age: 24,
};
타입 별칭을 사용한 경우와 인터페이스를 사용한 위의 예시를 보면 큰 차이가 없다. 하지만 VSCode 프리뷰로 확인한 결과와 확장 여부에서 큰 차이가 존재한다.
인터페이스로 선언한 타입을 프리뷰로 확인하면 인터페이스를 선언한 이름 밖에 띄워주지 않는다.
하지만 타입 별칭을 사용하여 프리뷰로 확인한 결과 선언한 타입과 부여한 이름 등을 모두 확인할 수 있을 것이다.
VSCode 상에서는 모든 선언한 타입을 보여주기 때문에 타입 별칭을 사용하기 더 편리할 수 있다.
하지만, 타입 별칭 보다는 인터페이스를 사용할 것을 추천한다.
그 이유는 확장 가능 여부 때문이다. 인터페이스는 확장이 가능하지만, 타입 별칭을 사용하면 확장이 불가능하다.
[TypeScript] 인터페이스(Interface)
인터페이스(Interface)
인터페이스는 상호 간 정의한 약속 혹은 규칙을 의미한다.
프로그래밍 언어 중 자바에서 인터페이스라는 개념을 들어본 경험이 있을 것이다.
하지만 타입스크립트의 인터페이스와 자바의 인터페이스에는 차이가 있다.
자바에서 인터페이스는 추상 메소드, 상수만을 정의한 클래스를 위주로 다루고, 타입스크립트에서 인터페이스는 객체를 위주로 다룬다.
즉, 요약하자면 타입스크립트에서 인터페이스는 객체의 설계도라 타입을 미리 정의한 틀로 사용할 수 있다.
주로 여러 함수가 특정한 타입을 동일하게 가져야 할 경우, 동일한 타입을 정의하여 인터페이스를 사용할 수 있다.
인터페이스를 통해 선언된 프로퍼티나 메소드의 구현을 강제로 하여 클래스와 함수 등 간의 일관성을 유지할 수 있도록 한다.
타입스크립트에서 인터페이스 아래와 같은 범주에 대해 규칙을 정의할 수 있다.
위와 같이 인터페이스를 정의하고 정의한 인터페이스 자체를 타입으로 줘서 객체를 생성할 수 있다.
옵션 속성
인터페이스를 사용하다 보면, 인터페이스에 정의된 속성을 다 사용하고 싶지 않을 경우가 생긴다.
하지만 정의된 속성을 다 사용하지 않은 경우 아래와 같은 에러가 발생할 것이다.
이때는 옵션 속성을 이용해 인터페이스를 정의하면 된다.
옵션 속성은 속성의 끝에 물음표(?)를 붙여 사용하면 된다.
앞선 예제에서 옵션 속성을 사용한 결과 에러가 발생하지 않는 것을 확인할 수 있을 것이다.
※ 옵션 속성 장점
옵션 속성은 단순히 인터페이스를 사용할 때 속성을 선택적으로 적용할 수 있는 것 뿐만 아니라 인터페이스에 정의되어 있지 않은 속성에 대해 인지시켜 줄 수 있는 장점이 있다.
읽기 전용 속성
읽기 전용 속성은 인터페이스로 객체를 처음 생성할 때만 값을 할당하고 그 이후에는 변경할 수 없는 속성을 의미한다.
읽기 전용 속성은 속성 이름 앞에 readonly만 붙여 적용하면 된다.
readonly를 사용한 속성은 인터페이스로 객체를 처음 선언하여 값을 대입할 때는 문제가 되지 않는다.
하지만 처음 선언 후 따로 프로퍼티에 접근해 값을 수정하면 오류가 발생한다.
readonly를 보다보면 변수를 선언할 때 사용하는 const와 유사하다고 느낄 것이다.
readonly와 const 모두 초기 값을 선언하면 이 후 값을 수정하지 못하는 점은 같지만, const는 변수에 사용하고 readonly는 프로퍼티에 사용한다는 차이가 있다.
< readonly 활용 >
readonly를 사용하는 경우 모든 속성을 readonly로 지정해야 할 경우가 생길 것이다. 이때는 모든 프로퍼티 각각에 readonly를 붙여주는 방식 보다는 따로 유틸리티나 단언 타입을 활용해 구현하는 방식을 선호한다.
위 방식이 readonly를 모든 프로퍼티에 찍어내는 방식이다.
위 방식은 Readonly 유틸리티를 활용한 방식이다. 배열(Array)처럼 따로 Readonly라는 자료형이 있다고 생각하여 사용하는 것이 좋다.
< 읽기 전용 배열 >
배열을 선언할 때 ReadonlyArray<T> 타입을 사용하여 읽기 전용 배열을 생성할 수 있다.
ReadonlyArray<T>를 사용해 읽기 전용 배열을 선언하면 초기 값을 할당하는 것은 가능하지만, 선언 이후 값을 변경하는 것은 불가능하다.
함수 타입
인터페이스는 함수의 타입으로 사용할 수 있다.( 함수의 스펙(구조)에 인터페이스를 활용할 수 있다.)
함수의 타입으로 인터페이스를 사용할 때는 타입이 선언된 파라미터 리스트와 리턴 타입을 정의한다.
다음과 같이 함수의 타입으로 인터페이스를 정의한다면 인자의 타입과 반환 값의 타입을 정해주며 사용하면 된다.
클래스 타입
타입스크립트에서는 클래스를 사용하여 일정 조건을 만족하도록 타입 규칙을 정할 수 있다.
클래스는 자바나 C#에서도 많이 들어봤을 것이다.
인터페이스로 클래스를 정의하는 경우, implements 키워드를 사용해 클래스 정의 뒤에 붙여주면 된다.
클래스 선언문의 implements 뒤에 인터페이스를 선언하면 해당 클래스는 지정된 인터페이스를 반드시 구현해야 한다.
우리는 클래스를 사용함으로써 인터페이스를 구현하는 클래스의 일관성을 유지할 수 있다.
먼저, 타입스크립트에서 클래스르 사용할 때, 클래스 몸체에 클래스 프로퍼티를 사전 선언해야 한다.
하이브리드 타입
인터페이스 확장
인터페이스는 클래스처럼 인터페이스 간 확장이 가능하다.
인터페이스는 extends 키워드를 사용하여 인터페이스 또는 클래스를 상속받을 수 있다.
인터페이스는 복수의 인터페이스를 상속받을 수 있으며, 인터페이스 뿐만 아니라 클래스도 상속받을 수 있다.
인터페이스 vs 타입 별칭
< 타입 별칭 >
타입 별칭은 특정 타입이나 인터페이스를 참조할 수 있는 타입 변수를 의미한다.
타입 별칭은 위와 같이 string, number와 같이 간단한 타입 뿐 아니라 인터페이스 정도 구의 복잡한 타입이나 제너릭 등에도 사용할 수 있다.
타입 별칭은 새로운 타입 값을 하나 생성하는 것이 아닌 정의한 타입에 대해 나중에 쉽게 참고할 수 있도록 이름을 부여하는 것이다.
< 인터페이스와 타입 별칭 차이 >
타입 별칭을 사용한 경우와 인터페이스를 사용한 위의 예시를 보면 큰 차이가 없다. 하지만 VSCode 프리뷰로 확인한 결과와 확장 여부에서 큰 차이가 존재한다.
인터페이스로 선언한 타입을 프리뷰로 확인하면 인터페이스를 선언한 이름 밖에 띄워주지 않는다.
하지만 타입 별칭을 사용하여 프리뷰로 확인한 결과 선언한 타입과 부여한 이름 등을 모두 확인할 수 있을 것이다.
VSCode 상에서는 모든 선언한 타입을 보여주기 때문에 타입 별칭을 사용하기 더 편리할 수 있다.
하지만, 타입 별칭 보다는 인터페이스를 사용할 것을 추천한다.
그 이유는 확장 가능 여부 때문이다. 인터페이스는 확장이 가능하지만, 타입 별칭을 사용하면 확장이 불가능하다.
그래서 타입 별칭을 사용하는 것 보다는 인터페이스를 사용할 것을 권장한다.
'Front-End > TypeScript' 카테고리의 다른 글