TIL.TypeScript_ 인터페이스

chloe·2021년 3월 17일
0

Typescript

목록 보기
2/8
post-thumbnail

TypeScript의 핵심 원칙 중 하나는 타입 검사가 값의 형태에 초점을 맞추고 있다는 것이다. 이를 덕 타이핑 혹은 구조적 타이핑이라고도 한다. TypeScript에서 인터페이스는 이런 타입들의 이름을 짓는 역할을 하고 코드 안의 계약을 정의하는 것뿐만 아니라 프로젝트 외부에서 사용하는 코드의 계약을 정의하는 강력한 방법이다.

첫 번째 인터페이스

function printLabel(labeledObj:{label:string}){
  console.log(labeledObj.label);
}

let myObj={size:10, label:"Size 10 Object"};
printLabel(myObj);

타입 검사는 printLabel 호출을 확인한다. printLabel함수는 string타입 label을 갖는 객체를 하나의 매개변수로 가진다. 이 객체가 실제로는 더 많은 프로퍼티를 갖고 있지만, 컴파일러는 최소한 필요한 프로퍼티가 있는지 타입이 잘맞는지만 검사한다.

interface LabeledValue{
  label:string;
}
function printLabel(labeledObj:LabeledValue){
  console.log(labeledObj.label);
}

let myObj={size:10, label:"Size 10 Object"};
printLabel(myObj);

LabeledValue인터페이스는 여전히 문자열 타입의 label 프로퍼티 하나를 가진다는 것을 의미한다.

선택적 프로퍼티(Optional Properties)

인터페이스의 모든 프로퍼티가 필요한 것은 아니다. 어떤 조건에서만 존재하거나 아예 없을 수도 있다.

interface SquareConfig{
  color?:string;
  width?:number;
}
function createSquare(config:SquareConfig):{color:string; area:number}{
  let newSquare={ color:"white",area:100};
  if(config.color){
    newSquare.color=config.color;
  }
  if(config.width){
    newSquare.area=config.width*config.width;
  }
  return newSquare;
}
let mySquare=createSquare({color:"black"});

선택적 프로퍼티를 가지는 인터페이스는 다른 인터페이스와 비슷하게 작성되고, 선택적 프로퍼티는 선언에서 프로퍼티 이름 끝에 ?를 붙여 표시한다.
선택적 프로퍼티의 이점은 인터페이스에 속하지 않는 프로퍼티의 사용을 방지하면서 사용가능한 속성을 기술하는 것이다.

읽기전용 프로퍼티 (Readonly properties)

일부 프로퍼티들은 객체가 처음 생성될 때만 수정 가능해야 한다. 프로퍼티 이름 앞에 readonly를 넣어서 이를 지정할 수 있다.

interface Point{
  readonly x:number;
  readonly y:number;
}

객체 리터럴을 할당하여 Point를 생성한다. 할당 후에는 x,y를 수정할 수 없다.

let p1:Point={x:10,y:20};
p1.x=5; //오류

함수 타입 (Function Types)

인터페이스는 JavaScript객체가 가질 수 있는 넓은 범위의 형태를 기술할 수 있다. 프로퍼티로 객체를 기술하는 것 외에, 인터페이스는 함수 타입을 설명할 수 있다.
인터페이스로 함수 타입을 기술하기 위해, 인터페이스에 호출서명(call signature)를 전달한다. 이는 매개변수 목록과 반환 타입만 주어진 함수 선언과 비슷하다.

interface SearchFunc {
  (source:string, subString:string):boolean;
}

한번 정의되면, 함수 타입 인터페이스는 다른 인터페이스처럼 사용할 수 있다. 여기서 함수 타입의 변수를 만들고 같은 타입의 함수 값으로 할당하는 방법을 보여준다.

let mySearch :SearchFunc;
mySearch=function(source:string, subString:string){
  let result =source.search(subString);
  return result > -1;
}

올바른 함수 타입 검사를 위해, 매개변수의 이름이 같을 필요는 없다. 예를들어, 위 예제를 아래와 같이 쓸 수 있다.

let mySearch: SearchFunc;
mySearch=function(src:string,sub:string) :boolean{
  let result =src.search(sub);
  return result >-1;
}

인덱서블 타입(Indexable Types)

인터페이스로 함수 타입을 설명하는 방법과 유사하게, a[10]이나 ageMap["daniel"]처럼 타입을 인덱스로 기술할 수 있다.

interface StringArray {
  [index:number]:string;
}
let myArray:StringArray;
myArray=["Bob","Fred"];
let myStr:string =myArray[0];

위에서 인덱스 서명이 있는 StringArray 인터페이스가 있다. 이 인덱스 서명은 StringArray가 number로 색인화(indexed)되면 string을 반환할 것을 나타낸다.
인덱스 서명을 지원하는 타입에는 두 가지가 있다 문자열,숫자

두 타입의 인덱서(indexer)를 모두 지원하는 것은 가능하지만, 숫자 인덱서에서 반환된 타입은 반드시 문자열 인덱서에서 반환된 타입의 하위타입이어야 한다.
왜냐하면 number로 인덱싱할 때 JavaScript는 실제로 객체를 인덱싱하기 전에 string으로 변환하기 때문이다. 즉, 100(number)로 인덱싱하는 것은 "100"(string)로 인덱싱하는 것과 같기에 서로 일관성있어야 한다.

class Animal{
  name:string;
}
class Dog extends Animal {
  breed:string;
}

//오류: 숫자형 문자열로 인덱싱을 하면 완전히 다른 타입의 Animal을 얻게 될 것이다!
interface NotOkay{
  [x:number]:Animal;
  [x:string]:Dog;
  

참고:https://typescript-kr.github.io/pages/interfaces.html

profile
Front-end Developer 👩🏻‍💻

0개의 댓글