[enum]
· 열거형 데이터 타입
· 상수의 그룹화에 좋은 타입
· 코드 가독성↑, 명확한 상수 값 정의
· 값을 할당하지 않으면 0부터 자동으로 숫자 값 매핑 - 특정 값 직접 할당 가능
· 여기서 특정 값은 number, string만 가능
· 장점 : 간단한 상수 값 그룹화하여 관리하기 편함, 값이 변하면 안된다는 조건(상수)
[object literal] : 객체 리터럴
· const, let 키워드 사용
· key-value pair
· 모든 타입의 값 할당 가능
· 코드 내에서 사용 전에 값이 할당되기 때문에 런타임 에러 방지 가능
· 장점 : 값이나 데이터타입 변경 가능, 복잡한 구조 & 다양한 데이터 타입 사용시 좋음
(1) Partial< T >
· 모든 속성을 선택적으로 만든다.
· 기존 타입의 일부 속성만 제공하는 객체 생성 가능
· 기존에 없는 속성은 넣을 수 없음.
(2) Required< T >
· 모든 속성 필수
· 예시 코드 ↓
interface Person {
name: string;
age: number;
address?: string; // 속성 명 뒤에 붙는 ?가 뭘까요
}
이 경우 address뒤에 붙는 ?는 address 가 선택적 속성이라는 뜻
어느 경우에서 필수적으로 받아야한다면
type RequiredPerson = Required<Person>;
이렇게 작성 가능 / 이 경우만을 위해서 Person 객체 변경 x
(3) Readonly< T >
· T의 모든 속성을 읽기 전용으로 만든다.
· 객체의 상수화
· 모든 속성이 readonly가 아닌 객체도 완전한 불변 객체 취급이 가능하다.
(4) Pick< T, K >
· K 속성들만 선택하여 새로운 타입을 만든다.
· 일부 속성만 포함하는 객체 생성 가능
· 속성1, 속성2, 속성3을 가지는 객체B에서 속성1, 속성2만 가져가고 싶은 경우
type A = Pick<B, "속성1" | "속성2">
(5) Omit< T, K >
· Pick의 반대 개념
· K 속성을 제외한 새로운 타입을 만든다.
· 속성3만 제외
· 필요한 경우 : A에 속성이 30개인데 29개만 가지고 싶을 때 29개를 Pick으로 선택하는 것보다 1개만 Omit하는 것이 효율적이다.
type A = Omit<B, "속성3">
· 객체를 만들기 위한 틀
· 클래스 구성 요소 - 속성 : 객체의 성질 , 메소드 : 객체의 성질 변화, 객체 제공 기능 사용
· class 키워드 사용하여 정의
· 클래스 기반으로 생성, 클래스의 인스턴스(* 자주 헷갈리는 중..)
· 클래스 속성과 메서드를 정의하고 new 키워드 사용하여 생성
· constructor(){}
· 인스턴스를 생성하고 초기화 할 때 사용되는 메소드 - 이후에는 사용하지 않음
· 인스턴스 생성 시 자동 호출
· 인스턴스 내에 하나만 존재
· 인스턴스를 초기화하면서 생성 시 꼭 실행되어야 하는 로직을 넣을 수 있음
· 속성과 메서드에 사용 가능
(1) public
· 외부에서도 접근 가능
· 선언이 안되어있으면 기본적으로 public 적용
(2) private
· 클래스 내부에서만 접근 가능
· 보통 클래스 속성 대부분에 private 설정
→ 외부에서 변경x, 클래스 속성 보거나 편집하려면 getter/setter 메서드 준비하는 것이 관례
(3) protected
· 클래스 내부 및 해당 클래스를 상속 받은 자식 클래스에서만 접근 가능
· 기존 클래스의 속성과 메서드를 물려받아서 새로운 클래스를 정의
· extends 키워드 사용
· super() → 부모 클래스의 생성자를 호출 / 부모 클래스 참조
· 부모 클래스의 함수 동작을 재정의해서 사용 → 메소드 오버라이딩
· 슈퍼타입이 필요한 곳에는 어디든 서브타입을 안전하게 사용 가능
· any는 모든 것의 슈퍼타입
· upcasting : 서브타입 → 슈퍼타입 / 타입 변환이 암시작으로 이루어져 별도 구문 필요 없음
+ 서브타입 객체를 슈퍼타입 객체로 다루면 유연하게 활용 가능하다.
· downcasting : 슈퍼타입 → 서브타입 / as키워드로 명시적 타입 변환
+ 서브타입 메서드 사용 필요 시 적용
· 인스턴스화 할 수 없는 클래스 → =new 할 수 없음.
· 상속을 통해서 자식 클래스에서 메소드를 각각 구현하도록 강제
· 최소한의 기본 메소드 정의는 가능하지만 핵심 기능의 구현은 전부 자식 클래스에게 위임
· abstract 키워드 사용하여 정의
· 1개 이상의 추상 함수가 있는 것이 일반적
· 추상클래스를 상속받게 되면 그 안의 추상 함수를 반드시 구현해야 한다. / 안하면 오류
· TypeScript에서 객체 타입을 정의하는데 사용
· 객체가 가져야 하는 속성과 메소드 정의
· 인터페이스는 규약과 같기 때문에 객체는 인터페이스를 반드시 준수해야 한다.
· 구현부 제공 여부
추상클래스 : 클래스의 기본 구현 제공
인터페이스 : 객체의 구조만을 정의
· 상속 메커니즘
추상클래스 : 단일 상속만 지원
인터페이스 : 다중 상속 지원 / 하나의 클래스가 여러 인터페이스 구현 가능
· 구현 메커니즘
추상클래스 : 상속받은 자식 클래스는 반드시 추상 함수 구현
인터페이스 : 인터페이스에 정의된 모든 메서드 전부 구현
· 언제 쓰면 좋을까?
추상클래스 : 기본 구현을 제공하고 상속을 통해 확장
인터페이스 : 객체가 특정 구조를 완벽하게 준수하도록 강제
(1) S (SRP 단일 책임 원칙)
· 클래스는 하나의 책임만 가져야한다. / 유저 서비스 클래스에서는 유저 관련 액션만 해야 한다.
(2) O (OCP 개방 폐쇄 원칙)
· 클래스는 확장에 대해서는 열려 있어야 하고 / 수정에 대해서는 닫혀 있어야 한다.
· 클래스의 기존 코드를 변경하지 않고 기능 확장
· 인터페이스와 상속을 통해서 가능
(3) L (LSP 리스코프 치환 원칙)
· 서브타입은 기반이 되는 슈퍼타입을 대체할 수 있어야한다.
· 자식 클래스는 부모 클래스의 기능을 수정하지 않아도 부모 클래스와 호환 되어야 한다.
= 논리적으로 엄격하게 관계 정립
(4) I (ISP 인터페이스 분리 원칙)
· 사용하지 않는 인터페이스의 영향을 받지 않아야 한다.
· 해당 클래스에게 무의미한 메소드의 구현을 막는다.
· 인터페이스는 필요한 만큼만 정의
· 클래스는 상황에 맞게 필요한 인터페이스들을 구현해야 한다.
(5) D (DIP 의존성 역전 원칙)
· 하위 수준 모듈(구현 클래스)보다 상위 수준 모듈(인터페이스)에 의존해야 한다.
많은 도움이 되었습니다, 감사합니다.