본문 바로가기
Elice SW 2/TIL

DAY 25 - TIL

by 자이구 2022. 5. 8.

인터페이스 

  • 일반적으로 변수, 함수, 클래스에 타입 체크를 위해 사용
  • 직접 인스턴스를 생성할 수 없고 모든 메소드가 추상 메소드
  • 추상 클래스의 추산 메소드와 달리 abstract 키워드 사용불가
  • ES6는 인터페이스를 지원하지 않지만 타입스크립트는 인터페이스를 지원

인터페이스 사용 이유

  • 타입의 이름을 짓고 코드 안의 계약을 정의
  • 프로젝트 외부에서 사용하는 코드의 계약을 정의하는 강력한 방법
  • 객체의 스펙(속성,속성타입)/함수의 파라미터/함수의 스펙(파라미터,리턴타입)/배열과 객체에 접근하는 방식/클래스

 

프로퍼티

컴파일러는 프로퍼티의 두 가지 요소, 필수요소 프로퍼티의 유무와 프로퍼티 타입을 검사

 

optional properties

  • 프로퍼티 선언 시 이름 끝에 ?를 붙여서 표시
  • 인터페이스에 속하지 않은 프로퍼티의 사용을 방지하면서, 사용 가능한 프로퍼티를 기술할 때 사용

Readonly properties

  • 객체가 처음 생성될 때만 값 설정이 가능하고, 이후 수정이 불가능
  • 프로퍼티 이름 앞에 readonly를 붙여 사용
  • 변수는 const를 사용하고 프로퍼티는 readonly를 사용

 

인터페이스 타입

타입스크립트에서 인터페이스는 함수, 클래스에서 사용

 

함수

  • JS 객체가 가질 수 있는 넓은 범위의 형태를 기술
  • 프로퍼티로 객체를 기술하는 것 외에도, 인터페이스는 함수 타입을 설명
  • 함수의 인자의 타입과 반환 값의 타입을 정의
  • 함수의 타입을 정의할 때에도 사용
interface SearchFunc {
	(source: string, subString: string): boolean
}
// 변수로 직접 함수 값이 할당되었기 때문에 인수 타입 생략 가능
// TypeScript의 문맥상 타이핑 (contextual typing)이 인수 타입 추론

let mySearch: SearchFunc
mySearch = function (src, sub) {
	let result = src.search(sub);
	return result > -1;
}
// error: Type '(src: string, sub: string) => string' is not assignable to type 'SearchFunc'.
// Type 'string' is not assignable to type 'boolean'.

mySearch = function (src, sub) {
	let result = src.search(sub);
	return "string";
}

 

클래스

  • 클래스가 특정 통신 프로토콜을 충족하도록 명시적으로 강제
  • Java와 같은 언어에서 일반적으로 인터페이스를 사용하는 방법과 동일
  • 클래스가 특정 계약을 충족하도록 명시적으로 강제

hybrid type

  • JS의 유연하고 동적인 타입 특성에 따라 인터페이스 역시 여러 가지 타입을 조합할 수 있음
  • 함수 타입이면서 객체 타입을 정의할 수 있는 인터페이스도 구현 가능
interface Counter {
	(start: number): string
	interval: number
	reset(): void
}

function getCounter(): Counter {
	let counter = function (start: number) {} as Counter
	counter.interval = 123;
	counter.reset = function () {}
	return counter;
}

let c = getCounter();
c(10);
c.reset();
c.interval = 5.0;

 

Generic

  • 정적 type 언어는 클래스나 함수를 정의할 때 type을 선언해야함
  • Generic은 코드를 작성할 때가 아니라 코드가 수행될 때 타입을 명시
  • 코드를 작성할 때 식멸자를 써서 아직 정해지지 않은 타입을 표시

Generic을 사용하는 이유

  • 재사용성이 높은 함수와 클래스를 생성할 수 있음
  • 오류를 쉽게 포착 
  • Generic도 any처럼 미리 타입을 지정하지는 않지만, 타입을 체크해 컴파일러가 오류를 찾을 수 있음

Generic으로 함수와 클래스 만들기

 

함수

function sort<T>(items: T[]): T[] {
	return items.sort();
}
const nums: number[] = [1, 2, 3, 4];
const chars: string[] = ["a", "b", "c", "d"];

sort<number>(nums);
sort<string>(chars);

클래스

class Queue<T> {
	protected data: Array<T> = [];
	push(item: T) {
		this.data.push(item);
}
	pop(): T | undefined {
		return this.data.shift();
	}
}

const numberQueue = new Queue<number>();

numberQueue.push(0);
numberQueue.push("1"); // 의도하지 않은 실수를 사전 검출 가능
numberQueue.push(+"1"); // 실수를 사전 인지하고 수정할 수 있다

 

Union type

  • "|"를 사용해 두 개 이상의 타입을 선언하는 방식
  • Union과 Generic 모두 여러 타입을 다룰 수 있음
  • Union은 선언한 콩통된 메소드만 사용 가능
  • 리턴 값이 하나의 타입이 아닌 선언된 Union 타입으로 지정
// 1. Union type
const printMessage = (message: string | number) => {
	return message;
}
const message1 = printMessage(1234);
const message2 = printMessage("hello world !");
// string과 number type의 공통된 메소드만 사용 가능하다
// error: length does not exist on type string | number
message1.length;

// 2. generic
const printMessage2 = <T>(message: T) => {
	return message;
}
const message1 = printMessage2<String>("hello world !");
message1.length;

 

제약조건

원하지 않은 속성에 접근하는 것을 막기 위해 Generic에 제약조건을 사용

 

Constraints

  • 특정 타입들로만 동작하는 Generic 함수를 만들 때 사용
  • Generic T에 제약 조건을 설정(문자열/숫자)
  • 제약 조건을 벗어나는 타입을 선언하면 에러가 발생

keyof

  • 두 객체를 비교할 때 사용
  •  keyof는 Object의 key들의 lieteral 값들을 가져옴

 

디자인 패턴

  • 객체를 생성하는 인터페이스만 미리 정의하고, 인스턴스를 만들 클래스의 결정은 서브 클래스가 내리는 패턴
  • 여러 개의 서브 클래스를 가진 슈퍼 클래스가 있을 때, 입력에 따라 하나의 서브 클래스의 인스턴스를 반환

'Elice SW 2 > TIL' 카테고리의 다른 글

DAY 27 - TIL  (1) 2022.05.12
DAY 26 - TIL  (0) 2022.05.09
DAY 24 - TIL (2)  (1) 2022.05.07
DAY 24 - TIL  (0) 2022.05.07
DAY 23 - TIL  (0) 2022.05.07

댓글