TypeScript 공부(5)

김희목·2024년 8월 26일
0

패스트캠퍼스

목록 보기
48/53

인터페이스(Interface)

선택적 속성 - ?
읽기전용 속성 - readonly

interface User {
	name: string
    readonly age: number
    isValid?: boolean
}

const heropy: User = {
	name: 'Heropy',
    age: 85,
    isValid: true
}

heropy.isValid = false
heropy.age = 22

const neo: User = {
	name: 'Neo',
    age: 102
}

isValid 부분에 ? 즉 선택적 속성을 추가하면, 아래 예시 처럼 isValid 부분을 추가해도 되고, 생략해도 되는 선택을 할 수 있습니다. 또한 만약 ? 기호가 없다면 필수적으로 추가되어야 합니다.

읽기전용 속성이란 인터페이스에서 readonly를 추가하면, 해당 요소는 재할당이 불가능하고, 변경이 불가능한 읽기만 가능하게 바뀌게 됩니다. 그래서 해당 heropy.age = 22 라는 코드는 오류가 발생되게 됩니다.

추가 정보

함수 타입 - 호출 시그니처(Call Signature)

객체 데이터의 타입만 지정하는 것이 아니고 함수의 타입도 지정할 수 있습니다.

interface GetName {
  (message: string): string // 소괄호를 통해서 만들어진 타입지정을 호출 시그니처 라고 합니다.
}
interface User {
	name: string
    age: number
    getName: GetName
}
const heropy: User = {
  name: 'Heropy',
  age: 85,
  getName(message: string) {
    console.log(message)
    return this.name
  }
}

heropy.getName('Hello~') // 오류 GetName 형식에 호출 시그니처가 없습니다.

GetName의 interface가 작성되지 않았을 때 오류가 발생했지만 소괄호를 통한 타입지정 즉, 호출 시그니처를 작성해 줌으로 써 해결이 된것을 볼 수 있습니다.

interface User {
	name: string
    age: number
    getName: (message: string) => string
}
const heropy: User = {
  name: 'Heropy',
  age: 85,
  getName(message: string) {
    console.log(message)
    return this.name
  }
}

heropy.getName('Hello~') // 오류 GetName 형식에 호출 시그니처가 없습니다.

다른 방식으로는 인턴페이스의 속성을 지정할 때 그 속성이 함수라면 즉 메소드라면, 이렇게 우리가 예전에 배운 함수타입 그래서 화살표 함수처럼 타입을 지정하는 방식을 쓸 수 있습니다.

하지만 지정하는 타입을 재사용해야 하는 경우라면, 인터페이스를 통해 호출 시그니처 방식으로 함수의 타입을 지정해주는 것이 좋습니다.

인덱스 가능 타입 - 인덱스 시그니처(Index Sginature)

우리가 기본적으로 객체 데이터의 속성을 줘야 할 때 이렇게 점 표기법(heropy.age)을 사용하게 되는데 이 방법 말고도 우리는 대괄호 표기법을 사용할 수 있습니다.

그렇게 대괄표 표기법을 사용해서 속성을 줘야 하는 방법을 인덱싱한다 라고 이야기 합니다.
이런식으로 인덱싱할 때는 인터페이스에 인덱스 가능 타입이 지정이 되어 있어야 합니다.

인덱스 가능 타입은 대표적으로 배열데이터라던가, 객체데이터에 타입을 지정할 수 있는 인터페이스 방식입니다.

//배열
interface Fruits {
  [item: number]: string
}
const fruits: Fruits = ['Apple', 'Banana', 'Cherry']
console.log(fruits)

//객체
interface User {
  [key: string]: unknown
  name: string
  age: number
}
const heropy: User = {
  name: 'Heropy',
  age: 85
}
heropy['isValid'] = true
heropy['emails'] = ['thesecon@gamil.com', 'test@gmail.com']
console.log(heropy)

예제2)

interface Payload {
  [key: string]: unknown
}

function logValues(payload: Payload) {
  for (const key in payload) {
    console.log(payload[key])
  }
}

interface User {
  [key: string]: unknown
  name: string
  age: number
  isValid: boolean
}

const heropy: User = {
  name: 'Heropy',
  age: 85,
  isValid: true
}
logValues(heropy)

확장(상속)

자바스크립트에서 class를 사용할 때 extends를 사용해서 상속이 가능했는데 인터페이스도 개념이 같습니다.

interface UserA {
  name: string
  age: number
}
interface UserB extends UserA {
  isValid: boolean
}

const heropy: UserA = {
  name: 'Neo',
  age: 85,
}

const kod: UserB = {
  name: 'Kod',
  age: 22,
  isValid: true
}

0개의 댓글