[study:러닝 타입스크립트] 07. 인터페이스

const job = '프론트엔드';·2023년 5월 15일
0

타입스크립트

목록 보기
6/8
post-thumbnail

일곱번째. 인터페이스

인터페이스란?

연관된 이름으로 객체 형태를 설명하는 또 다른 방법

  • 별칭으로 된 객체 타입과 여러면에서 유사
  • 일반적으로 더 읽기 쉬운 오류 메시지
  • 더 빠른 컴파일러 성능
  • 클래스와의 더 나은 상호 운용성을 위해 선호됨

7.1 타입 별칭 vs. 인터페이스

공통점

  • 할당 가능성 검사와 오류메시지는 거의 동일

차이점

  • 인터페이스는 속성 증가를 위해 병합 할 수 있음
  • 인터페이스는 클래스가 선언된 구조의 타입을 확인하는데 사용
  • 인터페이스에서 타입스크립트 타입 검사기가 더 빨리 작동(인터페이스는 타입 별칭이 하는 것처럼 새로운 객체 리터럴의 동적인 복사 붙여넣기보다 내부적으로 더 쉽게 캐시할 수 있는 명명된 타입을 선언)
  • 인터페이스는 이름 없는 객체 리터럴의 별칭이 아닌 이름 있는 객체로 간주(어려운 특이 케이스에서 나타나는 오류 메시지를 좀 더 쉽게 읽을 수 있음)

결과적으로

  • 인터페이스는 사용하는 것이 좋음
  • 타입 별칭의 유니언 타입과 같은 기능이 필요할 때까지는 인터페이스를 사용해라 !

7.2 속성 타입

7.2.1 선택적 속성

  • 객체 타입과 마찬가지로 모든 객체가 필수적으로 인터페이스 속성을 가질 필요는 없음
  • 타입 애너테이션 : 앞에 ?를 사용해 인터페이스의 속성이 선택적 속성임을 나타낼 수 있음
  • gazero 인터페이스를 사용하는 객체애 선택적 속성은 제공되거나(string으로 혹은 undefined로 제공) 생략할 수 있음

7.2.2 읽기 전용 속성

언제쓸까?

  • 인터페이스에 정의된 객체의 속성을 재할당하지 못하도록 인터페이스 사용자를 차단하고 싶을때
  • 속성 이름 앞에 readonly키워드를 추가해 다른 값으로 설정될 수 없음을 나타냄
  • readonly 제한자는 타입 시스켐에만 존재 & 인터페이스에서만 사용
  • readonly속성은 평소대로 읽을 수 있지만, 새로운 값으로 재할당하지 못함
  • Gazero 인터페이스의 name 속성에 접근하면 string을 반환
  • name에 새로운 값을 할당하면 오류 발생

writeable 쓰기 가능한 속성으로는 사용할 수 없을까? 있음 !

  • name 속성의 부모 객체는 함수 내부에서 name으로 명시적으로 사용되지 않았기 때문에 함수 밖에서 속성을 수정할 수 있음
  • 따라서, 쓰기 가능한 속성을 readonly 속성에 할당할 수 있음
  • gazerous는 Gazero를 사용할 수 있음
  • 즉, 쓰기 가능한 속성은 readonly 속성이 필요한 모든 위치에서 읽을 수 있음

cf. gazerous의 더 구체적인 버전인 Gazero를 읽음

  • 명시적 타입 애너테이션인 :Gazeo로 변수 gazerous를 선언하면 타입스크립트 name 속성이 readonly라고 가르킴

7.2.3 함수와 메서드

인터페이스 멤버를 함수로 선언하는 방법

  • 메서드 구문

인터페이스 멤버를

 member(): void

와 같이 객체의 멤버로 호출되는 함수로 선언

  • 속성 구문
    인터페이스 멤버를
member: () => void

와 같이 독립 함수와 동일하게 선언

  • method와 property 멤버는 둘 다 매개변수 없이 호출되어 string타입을 반환

선택적 속성사용

  • string 타입으로 반환되거나
  • 정의되지 않을 수 있음을 의미
  • 정의되지 않을 수 있는 개체는 호출할 수 없음
  • 메서드는 readonly로 선언할 수 없지만 속성은 가능

7.2.4 호출 시그니처

  • 인터페이스와 객체 타입은 호출 시그니처로 선언할 수 있음
  • 호출 시그니처는 함수처럼 호출하는 방식에 대한 타입 시스템
  • 호출 시그니처가 선언한 방식으로 호출되는 값만 인터페이스에 할당할 수 있음
  • 즉, 할당 가능한 매개변수와 반환 타입을 가진 함수임
  • 형식: 함수타입과 비슷하지만 콜론 대신 화살표로 표시

  • 사용자 정의 속성을 추가로 갖는 함수를 설명하는 데 사용
  • 타입스크립트는 함수 선언에 추가된 속성을 해당 함수 선언의 타입에 추가하는 것으로 인식

인터페이스 할당의 문제

7.2.5 인덱스 시그니처

  • 인덱스 시그니처 구문을 제공해 인터페이스의 객체가 임의의 키를 받고, 해당 키 아래의 특정 타입을 반환할 수 있음을 나타냄
  • 인덱스 시그니처는 일반 속성 정의와 유사하지만 키 다음에 타입이 있고 {[i: string]: ...}과 같이 배열의 대괄호를 갖음
  • GazeroFunctionCount 인터페이스는 number 값을 갖는 모든 string키를 허용하는 것으로 선언
  • 이런 타입의 객체는 값이 number면 string키가 아닌 그 어떤 키도 바인딩 할 수 없음
  • 인덱스 시그니처는 객체에 값을 할당할 때 편리함
  • 하지만 타입 안정성을 완벽하게 보장하지 않음
  • 인덱스 시그니처는 객체가 어떤 속성에 접근하든 값을 반환해야 함
1. WordGazero 인터페이스는 Date 값을 갖는 모든 string 키를 허용하는 것으로 선언
2. 객체는 값이 Date면 string키가 아닌 그 어떤 키도 바인딩 할 수 없음
3. gazeroDate 값은 Date 타입으로 Gayoung을 안전하게 반환하지만
4. 타입스크립트는 Beloved가 정의되지 않았음에도 불구하고 정의되었다고 생각하도록 속임
  • 따라서 키/값 쌍을 저장하려고 하는데 키를 미리 알 수 없다면 Map을 사용하는 것이 안전
  • get 메서드는 항상 키가 존재하지 않음을 나타내기 위해 |undefined 타입을 반환

속성과 인덱스 시그니처 혼합

  • 인터페이스는 명시적으로 명명된 속성과 포괄적인 용도의 string 인덱스 시그니처를 한 번에 포함할 수 있음
  • 인덱스시그니처: interface Gazero는 모든 속성을 number타입으로 선언 + 속성: Gayoung 속성이 존재해야 함
  • 또한, 속성 값의 초깃값을 지정해두면 Gazero를 사용하는 모든 객체의 Gayoung 속성은 반드시 지정해둔 값을 사용해야 함

숫자 인덱스 시그니처

  • 인덱스 시그니처는 키로 string 대신 number 타입을 사용할 수 있지만, 명명된 속성은 그 타입을 포괄적인 용도의 string 인덱스 시그니처의 타입으로 할당할 수 있어야 함
  • Gazero 인터페이스는 string을 string|undefined에 할당할 수 있지만, GazeroMore 인터페이스는 string|undefined를 string에 할당할 수 없음

7.2.6 중첩 인터페이스

  • 인터페이스 타입도 자체 인터페이스 타입 혹은 객체 타입을 속성으로 가질 수 있음
  • Gazero 인터페이스는 인라인 객체 타입인 author 속성과 Setting 인터페이스인 setting속성을 포함

7.3 인터페이스 확장

서로 형태가 비슷한 여러 개의 인터페이스를 갖게 될 수 있음

  • 타입스크립트는 인터페이스가 다른 인터페이스의 모든 멤버를 복사해서 선언할 수 잇는 확장된 인터페이스를 허용
  • 확장할 인터페이스의 이름 뒤에 extends 키워드를 추가해서 다른 인터페이스를 확장한 인터페이스라는 걸 표시
  • 파생 인터페이스를 준수하는 모든 객체가 기본 인터페이스의 모든 멤버도 가져야 한다는 것을 타입스크립트에 알려줌
  • Fine 인터페이스는 Gazero를 확장하므로 객체는 최소한 Fine의 year와 Gazero의 name 멤버가 모두 존재해야 함

7.3.1 재정의된 속성

  • 파생 인터페이스는 다른 타입으로 속성을 다시 선언해 기본 인터페이스의 속성을 재정의 하거나 대체할 수 있음
  • 속성을 재선언하는 대부분의 파생 인터페이스는 해당 속성을 유니언 타입의 더 구체적인 하위 집합으로 만들거나 속성을 기본 인터페이스의 타입에서 확장된 타입으로 만들기 위해 사용
  • GazeroNull 타입은 GazeroNonNull에서 null을 허용하지 않도록 재설정됨
  • GazeroNumeric의 name에는 number|string이 허용되지 않음(number|string은 string|null에 할당할 수 없기 때문)

7.3.2 다중 인터페이스 확장

  • 인터페이스는 여러 개의 다른 인터페이스를 확장해서 선언할 수 있음
  • 파생 인터페이스 이름에 있는 extends 키워드 뒤에 쉼표로 인터페이스 이름을 구분해 사용함

7.4 인터페이스 병합

  • 인터페이스의 중요한 특징 ! "병합"
  • 두 개의 인터페이스가 동일한 이름으로 동일한 스코프에 선언된 경우, 선언된 모든 필드를 포함하는 더 큰 인터페이스가 코드에 추가
  • 인터페이스 병합은 자주 사용되지 않음(코드를 이해하기가 어려워 질 수 있음)
  • 하지만, window 내장된 전역 인터페이스를 보강하는데 유리함
interface Window {
  environment: string;
}

window.environment;
//string 타입으로 !

7.4.1 이름이 충돌되는 멤버

  • 병합된 인터페이스는 타입이 다른 동일한 이름의 속성을 여러 번 선언 불가
  • 속성이 이미 인터페이스에 선언되어 있다면, 추후 병합된 인터페이스에서도 동일한 타입을 사용해야 함
  • 하지만 동일한 이름과 다른 시그니처를 가진 메서드는 정의할 수 있음 = 함수 오버로드 발생
profile
`나는 ${job} 개발자`

0개의 댓글