다형성
디형성이란 제네릭과 같이 특정 객체가 하나의 타입이 아닌 여러 가지 타입으로 표현될 수 있어서 재사용 가능한 형태로 구현될 수 있는 것을 말한다.
대표적 예시:
- 제네릭 : 데이터 타입을 일반화한 것으로 선언 시점이 아니라 생성 시점에 타입을 명시하여 다양한 타입을 사용할 수 있도록 하는 기법이다.
- 오버라이드 : 오버라이드는 상위 클래스의 메서드를 하위 클래스에서 재정의하는 것을 말한다. 메서드의 이름과 파라미터 개수, 타입이 동일해야 한다. 주로 상위 클래스의 동작을 상속받은 하위 클래스에서 변경하는 용도로 사용된다.
- 오버로딩: 같은 이름의 메서드나 생성자를 여러개 정의하는 것을 말한다. 이름은 같지만 매개변수의 개수나 타입이 다르게 정의된다.
타입 시그니쳐란 무엇인가
function functionName (parameter1: type, parameter2: type): returnType {
// 함수의 동작 코드
return value; // 반환값
}
함수, 서브루틴, 메소드 등의 입력과 출력을 정의하는 것. 함수에 포함된 인수의 수, 타입, 순서가 포함된다.
호출 시그니처는 무엇인가
함수에서 사용되는 매개변수와 리턴 값의 타입을 시그니처로 등록해서 추후 함수의 타입을 지정해야 할 떄 해당 시그니처를 통해 매개변수와 리턴 타입을 설정하는 것을 말한다.
-
type Operation = { (a: number, b: number): number; };
인덱스 시그니처는 무엇인가? 어떤 때에 사용하는 것인가?
- 객체의 속성을 유연하게 정의할 수 있다. 속성의 모든 이름을 미리 알지는 못하지만 값의 형태는 알고 있을 떄 사용 가능한 값의 타입을 지정할 수 있다. type UserData = { [key: string]: string | number; };
- 기본적으로 키와 value로 할당된 객체 내부 값들을 일일이 타입 지정을 하는 것이 아니라 하나의 시그니처를 통해서 설정하고자 할 떄 사용한다.
오브젝트 타입은 무엇인가?
객체 내부에 속성과 속성의 타입을 선언하는 방식의 타입이다. 일반적으로 식별자에 Object 타입을 지정하여 사용되는데, 이 경우 타입스크립트는 해당 오브젝트에 대한 속성 정보를 가지고 있지 않아 obj.id 와같이 접근하려 할 경우 에러를 발생시킨다.
때문에 이러한 문제를 해결하고자 객체 리터럴 타입으로 객체의 모든 프로퍼티에 타입을 지정하는 방식으로 사용한다.
type object1 = {
id:number,
name:string
}
인터페이스와 타입의 차이는?
- interface는 extends 키워드를 통해 확장할 수 있고, type은 & 키워드를이용하여 확장할 수 있다.
- interface는 선언적 확장이 가능하다. 하지만 type은 선언적 확장이 불가능하다.
- 인터페이스는 객체의 타입을 설정할 때 사용할 수 있으며,원시자료형에는 사용할 수 없다.
- 타입은 객체 타입을 정의할 때도 사용할 수 있다.
- interface는 computed value 사용이 불가능하고 타입은 사용 가능하다.
- 인터페이스는 합성할 경우 캐시가 되므로 컴파일 시에 성능이 좋다. 인터페이스를 합성하면 그 결과가 캐시되어 재사용되기 때문에 컴파일러가 더 빠르게 동작한다. 하지만 타입은 합성 과정에서 모든 구성요소에 대한 타입을 체크하기 때문에 컴파일시에 상대적으로 성능이 좋지 않다.
객체 타입을 정의할 때는 interface를 사용하는게 좋고, 단순 원시값이나 튜플, 유니언 타입을 선언할 떄는 type을 사용하는 것이 좋다.
한 클래스가 다른 클래스의 기능을 상속받지 않고, 대신 다른 클래스의 인스턴스를 포함하여 그 기능을 사용하는 방식을 의미한다.
타입스크립트에서 모듈이란 키워드는 무엇인가?
예제로 배우는 TypeScript 프로그래밍 - 모듈 (Module)
- 타입스크립트는 기본적으로 모두 변수와 함수 타입이 전역적으로 사용되기 때문에 복수개의 타입스크립트 파일이 있을 때 변수와 타입 사용에 있어 서로 충돌하거나 예기치 않게 다른 파일의 변수를 변경하는 등의 문제를 가질 수 있다. 이를 해결하기 위해 모듈과 네임스페이스를 사용한다.
- 모듈은 전역적 범위가 아닌 지역적 범위 스코프에서 실행되며, 해당 모듈의 외부 사용을 허용하기 위해 export를 사용해야 한다.
- 파일 내에 export 혹은 import를 선언하면 모듈로 취급한다. 없을 경우 전역적 범위를 가지는 스크립트로 취급된다.
타입스크립트에서 네임스페이스란?
- 타입스크립트의 모듈은 크게 두 가지로 나눠진다. 내부 모듈인 네임스페이스와 외부모듈인 export로 선언되어 외부로 공개된 모듈이다.
- 만약 파일의 상위에 import나 export가 존재하지 않을 경우, ts 파일은 전역 스코프에 영향을 미친다. 이 경우, 다른 파일의 변수명과 충돌 현상이 일어날 수 있다.
- 이때 네임스페이스 내부에 뱐수명을 선언하여 충돌을 예방할 수 있다. 외부에서 접근 가능하도록 export를 사용할 수 있으며, import 대신
/// <reference path="<file.ts>" />
를 사용하여 함수를 사용할 수 있다.
- 사실상 import export와 크게 다르지 않기 때문에 모던 코드들에 대해 ES module을 사용을 권장한다.
infer 키워드에 대하여
infer는 조건부 타입 중 하나로 조건에 따라 타입을 정의할 수 있는 기능이다. infer를 통해 제네릭 파라미터의 타입을 추론할 수 있다.
조건부 타입은 기본적으로 아래와 같다.
type MyConditionalType<T> = T extends U ? X : Y;
기본적으로 삼항 연산자의 형태를 가지고 있는데 조건에 따라 특정 타입을 지정하고 싶을 떄 사용하는 키워드이다.
타입스크립트 유틸리티 타입에 대하여 아는 것을 설명해보시오 (예)
- Readonly - Type의 모든 속성을 읽기 전용으로 변경한 새로운 타입 반환
- Omit - 타입에서 키로 속성을 생략하고 나머지를 선택한 새로운 타입 반환 (인터페이스)
- partial - 타입의 모든 속성을 선택적으로 변경한 새로운 타입 반환
as 키워드는 무엇인가?
타입 단언을 수행하는데 사용되는 키워드다. 개발자가 컴파일러에 특정 변수에 대한 타입 힌트를 주는 것으로 컴파일 단계에서 타입스크립트가 추론하지 못하는 타입을 as 키워드를 통해 명시해주는 것이다.
type assertion 을 피해야 하는 이유는?
타입 단언은 데이터의 타입을 명시하지만 런타임에서 데이터 타입에 영향을 주지는 않는다.
- 타입 안정성 감소 : 타입 단언을 사용하면 컴파일러의 타입 검사 기능을 우회한다.
- 타입 추론 방해 : 타입스크립트에서 제공하는 타입 추론 기능을 방해한다.
- 코드 복잡성 증가
타입 단언을 대신해 타입 가드를 사용하는 것이 좋다.
타입스크립트 가드란?
변수의 타입을 좁히는데 사용하는 매커니즘이다.기본적으로 타입스크립트는 변수의 타입을 컴파일할 때 결정하지만, 런타임에서 변수의 타입이 더 구체적이거나 제한적인 경우를 다루기 위해 타입 가드를 사용한다.
typeof A
: A 타입을 문자열로 반환
A instanceof B
: B의 프로토타입 체인에 A가 포함되었는지 boolean 반환 (A가 B의 인스턴스인지 확인)
a in A
: A의 속성중에 a가 있는지 boolean 반환
- 타입 가드는 기존의 타입 단언 시에 발생했던 타입 체킹을 우회하는 대신 타입 추론 범위를 제한시킬 목적으로 사용됩니다.
이넘 타입은 무엇인가? 꼭 사용하고 싶을 때는 어떻게 해야 하는가
- 이넘은 숫자 혹은 문자의 집합이다.
- 트리쉐이킹 및 키 벨류 값을 호출할 때 섞여서 부르는문제를 가지고 있다.
- 꼭 사용하고자 하면 const enum을 통해 사용할 수 있다. 하지만 순환 불가능하다.
extemds와 implements의 차이가 무엇인가
- 기능의 확장을 할 것인지, 해당 기능의 구현이 목적인지라는 큰 차이가 존재한다.
타입 추론과 컨텍스트 타이핑의 차이
- 타입 추론에는 최적 공통 타입과 문맥 타이핑 두 가지 방식이 존재한다.
- 전자는 표현식을 통해 가장 근접한 타입을 추론하는 방법이다.(다른 타입들과 가장 잘 호환되는 타입을 선정하게 되고 number와 null을 union type으로 구분하여 추론한다.
- 후자는 코드 문맥을 파악하여 가장 근접한 타입을 추론하는 방식이다. - 타입스크립트 검사기 관점에서 window.onmousedown에 할당되는 함수의 타입을 추론하기 위해 window.onmousedown을 검사하고, 타입 검사가 끝나고 나면 함수의 타입이 마수으 이벤트와 연관이 있다고 추론하기 때문에 button속성이 있지만 kangaroo 속성은 없다고 결론을 내린다.
트랜스파일링 과정에 대하여
- 소스코드 분석 : 타입스크립트 컴파일러는 입력된 타입스크립트 파일을 읽어와서 구문분석 단계에서 문법을 검사하고 추상구문트리(AST)를 생성한다.
- 타입 검사: 코드 안정성 검사를 수행하여 오류가 있다면 실패하고 컴파일이 종료된다.
- 자바스크립트 코드로 변환 : 오류가 없는 코드면 검사가 성공하여 자바스크립트 코드로 변환된다. 타입스크립트의 컴파일 결과로 만들어진 자바스크립트 코드는 Node.js 나 웹브라우저로 실행하면 자바스크립트 컴파일 과정을 거쳐 실행된다.
이 과정을 트랜스파일링이라고 부른다.
데코레이터란?(엥귤러에서 자주 사용됨)
- 데코레이터는 클래스 선언, 메서드(method), 접근자(accessor), 프로퍼티(property) 또는 매개변수(parameter)에 첨부할 수 있는 특수한 종류의 선언이다.
- 데코레이터 함수에는 target(현재타겟), key(속성이름), descriptor(설명)가 전달된다. (단, 어떤 멤버를 장식했느냐에 따라 인수가 달라짐)
- 메소드나 클래스 인스턴스가 만들어지는 런타임에 실행된다. 즉, 매번 실행되지 않는다.
- 데코레이터는 클래스 또는 클래스 내부의 생성자, 프로퍼티, 접근자, 메서드, 그리고 매개변수에만 장식될 수 있다.
unknown 타입이란?
- any 타입과 유사하게 모든 값을 허용하는 타입이지만, 할당된 값이 어떤 타입인지 모르기 때문에 함부로 프로퍼티나 연산을 할 수 없다.
- 예를 들어 unknown 타입을 곧바로 length를 찍을 경우 에러가 발생하지만, 조건문을 통해 타입을 검사하는 경우 문제없이 동작한다. 하지만 이때도 number의 length를 연산하게 될 경우 에러를 발생한다.
any
모든 타입을 허용합니다.TypeScript에서 타입 검사를 느슨하게 하므로 개발 당시에는 문제가 없으나 애플리케이션 또는 웹 페이지 개발 후 예기치 못한 문제가 발생할 가능성이 매우 높습니다.
unknown
모든 타입을 허용합니다.any 타입과는 다르게 프로퍼티 또는 연산을 하는 경우 컴파일러가 체크합니다. 그러므로 문제 되는 코드를 미리 예방할 수 있습니다.
never 타입이란?
타입스크립트에서 never 타입은 값의 공집합이다. 집합에 아무 값도 없기 때문에 네버 타입은 any 타입을 비롯하여 어떤 값도 가질 수 없다.
bottom type이라고도 불린다.
왜 사용하는가?
숫자에서 아무것도 존재하지 않는 것을 표현하기 위해 0이 존재하는 것처럼, 타입 시스템에서도 그 어떤 것도 불가능하다는 것을 나타내는 타입이 필요하다.
여기서 불가능 이라는 뜻은 다음과 같은 것을 의미한다.
- 어떤 값도 가질 수 없는 빈 타입
- 제네릭 및 함수에서 허용되지 않는 파라미터
- 호환 되지 않는 타입 교차
- 빈 유니언 타입 (유니언 했지만 아무것도 안되는 경우)
- 실행이 완료되면 caller에게 제어 권한을 반환하지 않는 (혹은 의도된) 함수의 반환 유형 (예: node의 process.exit())
- **void**와는 다르다. **void**는 함수가 caller에게 아무것도 리턴하지 않는 다는 것을 의미한다.
- rejected된 promise의 fulfill 값
- const p = Promise.reject('foo')// const p: Promise<never>
- 조건문(switch, if)
- 유니언
SOLID 원칙에 대하여 설명하라
- 단일 책임 원칙 (Single Responsibility Principle, SRP): 한 클래스는 하나의 책임만 가져야 합니다.
- 개방-폐쇄 원칙 (Open/Closed Principle, OCP): “소프트웨어 요소는 확장에는 열려 있으나 변경에는 닫혀 있어야 합니다.”
- 리스코프 치환 원칙 (Liskov Substitution Principle, LSP): “프로그램의 객체는 프로그램의 정확성을 깨뜨리지 않으면서 하위 타입의 인스턴스로 바꿀 수 있어야 합니다.”
- 인터페이스 분리 원칙 (Interface Segregation Principle, ISP): “특정 클라이언트를 위한 인터페이스 여러 개가 범용 인터페이스 하나보다 낫습니다.”
- 의존관계 역전 원칙 (Dependency Inversion Principle, DIP): 프로그래머는 “추상화에 의존해야지, 구체화에 의존하면 안됩니다.”
인터페이스에서 OCP 특징(상속 키워드)
소프트웨어 엔티티(클래스, 모듈, 함수 등)은 확장에 대해서는 열려있어야 하지만 변경에 대해서는 닫혀 있어야 한다. - 로버트 C.마틴
즉, 자신의 확장에는 열려 있고 주변의 변화에 대해서는 닫혀있어야 한다. 객체의 확장은 개방적으로, 객체의 수정은 패쇄적으로...
- 타입스크립트에서 인터페이스는 개방 폐쇄 원칙을 지원하는 중요한 도구이다. 인텊이스는 기존 인터페이스를 변경하지 않도 새로운 기능을 추가할 수 있는데 이는 상속 기능을 통해 이루어진다.
- 기존 인터페이스를 상속받아 새로운 인터페이스를 만들면, 재사용을 통해 새로운 맴버를 추가 가능하다.
'개발 > 스터디' 카테고리의 다른 글
AWS EC2와 ECS 그리고 Docker (0) | 2024.07.29 |
---|---|
기술 면접 준비 - React (5) 完 (0) | 2024.06.29 |
기술 면접 준비 - HTML, CSS 기본 (3) (0) | 2024.06.23 |
기술 면접 준비 - HTTP 기본 (2) (0) | 2024.06.17 |
기술 면접 준비 - Javascript 기본 (1) (2) | 2024.06.16 |