[Typescript] Interface

hyo·2023년 1월 25일
0

TypeScript

목록 보기
4/6
post-thumbnail

Interface

interface는 상호 간에 정의한 약속 혹은 규칙을 의미함.

// 기본 type 지정
let car = { brand: 'kia', createdAt: 2022 };
  function abc(obj: { createdAt: number }) {
    console.log(obj.createdAt);
  }
  abc(car); -> 2022

-> interface를 적용해본다.

// interface 적용
interface carInfo {
  createdAt: number
}

function abc(obj: carInfo) {
  console.log(obj.createdAt);
}
let car = { brand: 'kia', createdAt: 2022 }
abc(car); -> 2022

->

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

interface 옵션 속성

// interface에 하나의 타입을 더 추가한다.
interface carInfo {
    brand: string;
    createdAt: number;
    price: number;
  }

  function abc(obj: carInfo) {
    console.log('abc 함수 실행 : ', obj.createdAt);
  }
  let car = { brand: 'kia', createdAt: 2022 };
  abc(car); // 에러! 아래참고

위 코드에선 다음과 같은 typescript 에러가 나온다.
->

'{ brand: string; createdAt: number; }' 형식의 인수는 'carInfo' 형식의 매개 변수에 할당될 수 없습니다. 'price' 속성이 '{ brand: string; createdAt: number; }' 형식에 없지만 'carInfo' 형식에서 필수입니다.ts(2345)

즉, carInfo형식에서 price: number가 필수적이지만 car라는 인수(price속성이 없는)가 할당시키려해서 발생하는 에러가 나오는것이다.

위와같은 에러에선 ?를 속성 끝에 붙여서 해결한다.

interface carInfo {
    brand: string;
    createdAt: number;
    price?: number; // ?를 붙여서 에러를 해결하였다.
  }

  function abc(obj: carInfo) {
    console.log('abc 함수 실행 : ', obj.createdAt);
  }
  let car = { brand: 'kia', createdAt: 2022 };
  abc(car);

옵션 속성의 장점은 인터페이스를 사용할 때 속성을 선택적으로 적용할 수 있다는 것 뿐만 아니라 인터페이스에 정의되어 있지 않은 속성에 대해 인지시켜줄 수 있다.

읽기 전용 속성

읽기 전용 속성은 인터페이스로 객체를 처음 생성할 때만 값을 할당하고 이후에는 변경할 수 없는 속성을 의미한다.
아래처럼 readonly 속성을 앞에 붙인다.

// 인터페이스로 객체를 생성 후 객체 속성값 변경!
interface carInfo {
    brand: string;
  }
let car: carInfo = { brand: 'kia', createdAt: 2022 };

car.brand = 'hyundai';
console.log(car); -> { brand: 'hyundai', createdAt: 2022 }

// readonly 속성 추가 했을때 변경하려한다면?
interface carInfo {
    readonly brand: string;
  }
let car: carInfo = { brand: 'kia', createdAt: 2022 };

car.brand = 'hyundai'; // 에러! 아래 참고!
console.log(car);

위의 에러는 다음과 같이 나온다.
->

읽기 전용 속성이므로 'brand'에 할당할 수 없습니다.ts(2540)

읽기 전용 배열

ReadonlyArray<T> 타입을 사용하면 읽기 전용 배열을 생성가능!
ReadonlyArray로 선언하면 배열을 선언하는 시점에만 값을 정의 할 수 있다.

let arr: ReadonlyArray<number> = [0,1,2,3,4];
arr.push(5); // 에러!
arr[1] = 30; // 에러!

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

interface carInfo {
    brand?: string;
  }

  function abc(obj: carInfo) {
    
  }
  abc({createdAt: 2022}); // 에러! carInfo형식에 createdAt 가 없다.

위와 같은 에러가 나온다.
만약 이런 타입 추론을 무시하고 싶다면 아래와 같이 선언한다.

interface carInfo {
    brand?: string;
  }

  function abc(obj: carInfo) {
    
  }
  abc({createdAt: 2022} as carInfo);

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

interface carInfo {
    brand?: string;
    [propName: string]: any; // propName이라는 속성이 있는게 아니라 아무렇게나 이름을 지어도 된다. ex. [a: string]: any
  }

  function abc(obj: carInfo) {
    
  }
  abc({createdAt: 2022});

함수 타입

interface는 함수의 타입을 정의할 때에도 사용 가능!

interface login {
  (id: string, pw: string): boolean;
}
let isLogin: login;
isLogin = function() {
  return true;
}
isLogin('testId', '12345') -> true

interface 확장

interface carBrand {
    brand: string;
  }
  interface carName extends carBrand { // extends 를 사용하여 상속 가능!
    name: string;
  }
  let car = {} as carName;
  car.name = 'sportage';
  car.brand = 'kia';
  console.log(car); -> {name: 'sportage', brand: 'kia'}

추가적으로 속성을 넣고 싶다면?

interface carBrand {
    brand: string;
  }
  interface carName extends carBrand {
    name: string;
    [propName: string]: string;
  }
  let car = {} as carName;
  car.name = 'sportage';
  car.brand = 'kia';
  car.price = '4100';
  console.log(car); -> {name: 'sportage', brand: 'kia', price: '4100'}
profile
개발 재밌다

0개의 댓글