[엘리스] TIL #15

nerry·2022년 5월 11일
0
post-thumbnail

TypeScript

  • MS
  • 자바스크립트의 상위 집합으로 한계를 해결 함
  • 컴파일러가 자바스크립트로 변환해준다. (호환됨)

사용하는 이유

  1. 동적 타입을 정적으로 선언 가능하다. (미리 지정할 수 있음, 실행 되고 데이터를 본 뒤에 결정되는 것이 아님)

    ⇒ 오류를 코드 작성시 포착할 수 있다. JS는 실행하고 나서 알 수 있다.

  2. 타입 유추를 통한 타입 제어가 가능하다.

    ⇒ 매개변수를 통해 함수 반환 타입을 명시하지 않아도 유추하여 제어해줌

  3. 컴파일 시점에 오류를 포착할 수 있다.

  4. 추가 코드 기능이 있다

기본 Type

  • 변수나 함수에 Type을 정의할 수 있다.
  • 타입 표기 (Type Annotation)

기본 자료형 Primitive Type

실제 값을 저장하는 자료형

내장 함수를 사용 가능함 ⇒ JS의 처리 방식덕에 가능

  • string
  • boolean
  • number
  • null : 값이 의도적으로 비어있는 상태를 저장하는 타입
  • undefined : 아무 값이 할당되지 않았다는 값을 저장하는 타입

참조 자료형 Reference Type

Object 형식의 타입

메모리에 값을 주소로 저장! 주소와 일치하는 값을 출력

  • object : 기본 자료형에 해당하지 않은 타입 → 객체 { } , 배열 [ ]
  • array : 배열을 저장하는 타입, 제네릭을 사용해 타입 표기 가능
    let arr:number[]
    let arr:Array<number>

추가 제공 자료형

개발자 편의를 위해 추가 제공

  • tuple : 길이의 각 요소의 타입이 정해진 배열을 정해진 타입 let arr:[string,number]=["HI",6]
  • enum : 특정 값들의 집합을 저장하는 타입 enum Car {BUS,TAXI,SUV}; → 값이 0부터 할당됨
    • 인덱스 번호로 접근 가능
    • 값을 지정할 수 있음, 선택적으로도 가능
  • any : 모든 타입 저장 가능
    • 컴파일 중 타입 검사를 하지 않음
  • void : 함수에서 변환 값이 없을 때 사용
    • any의 반대 타입
    • 변수는 undefined, null만 할당 할 수 있다.
    • 함수는 반환 값을 설정할 수 없다. return이 없는 것
  • never : 발생할 수 없는 타입
    • 항상 오류 발생하거나 절대 반환하지 않는 반환 타입

      function neverEnd():never{
      	while(true){}
      	// throw Error('error') -> 가능
      	// break -> 하면 에러 발생, 함수가 종료되므로
      }

Utility types

공통 타입 변환을 용이하게 하기 위해 제공한다.

전역으로 사용 가능하다

  • Partial 프로퍼티를 선택적으로 만드는 타입을 구성, 부분적으로 이용함 주어진 타입의 모든 하위 타입 집합을 나타내는 타입을 반환한다. 저 중에 부분적으로 취해도 됨.
  • Readonly 읽기 전용으로 타입 설정, 수정 불가하다
  • Record<T,K> 집합 K로 구성하기 타입의 프로퍼티를 다른 타입에 매핑시키는데 사용한다.
  • Pick<T,K> K로만 이루어진 것으로 타입을 구성. 이외에 다른 것이 있다면 오류
  • Omit <T,K> 모든 프로퍼티 선택 후 K 프로퍼티를 제외한다.
  • Exclude<T,U> T-U를 한 것 T: a,b,c → U: a,b ⇒ 사용할 수 있는 타입 : c
  • Extract<T,U> T에서 U에 할당 할 수 있는 모든 속성을 추출하여 타입을 구성 T: a,b,c → U: a,f ⇒ 사용할 수 있는 타입 : a
  • NonNullable null과 undefined를 제외한 타입
  • Parameters 함수 타입 T의 매개변수 타입들의 튜플 타입을 구성
  • ConstructorParameters 생성자 함수 타입의 모든 매개변수 타입을 추출해 튜플 타입을 생성한다.
  • ReturnType T의 반환 타입으로 구성된 타입을 생성
  • Required T의 모든 프로퍼티가 필수로 설정된 타입을 구성한다.

함수

  • 매개변수(인자 값, Parameter): 정의시 사용되는 변수를 매개변수라고 한다.
  • 인수 : 함수 호출시 사용되는 값

일급 객체 first-class object

다른 객체들에 일반적으로 적용 가능한 연산을 모두 지원하는 객체

☑️  조건

  • 다른 함수에 매개변수로 제공 가능
  • 함수 반환으로 사용 가능
  • 변수에 할당 가능

⇒ 함수는 조건을 모두 충족하여 일급객체이다.

선언 방법 5가지

  1. 함수 선언식

    function world(name){
    	return `hello ${name}`;
    }
  2. 함수 표현식

    let world =function(name){
    	return `hello ${name};
    }
  3. 화살표 함수 표현식 Arrow Function

    let world =(name)=>{
    	return `hello ${name};
    }
  4. 단축형 화살표 함수 표현식

    let world = (name) => `hello ${name}`
  5. 함수 생성자 ⇒ 사용이 권장되지 않는다

    let world = new Function('name','return "hello"+name')

사용하기!

반환 타입을 추론하도록 권장 ⇒ contextual typing

매개 변수와 인수 타입이 호환 되게 작성한다.

인수 타입을 잘못 전달하면 에러가 난다.

⭐️ 타입 추론 contextual typing

  • 방정식의 한쪽에만 타입이 있어도 타입을 추론할 수 있다
let f12:(baseValue:number,increment:number)=> number = function(x,y){
	return x+y
}

매개변수

기본 매개변수

함수에 주어진 인자의 수는 기대하는 매개변수의 수와 일치해야한다.

선택적 매개변수 Optional Parameter

JS ⇒ 모든 매개변수가 선택적으로 들어오고, 없다면 undefined가 된다.

TS ⇒ 선택적 매개변수를 ?로서 이용할 수 있다

기본-초기화 매개변수 Default Parameter

TS에서는 값을 제공하지 않거나 undefined를 했을 때 매개변수 값을 할당 해둘 수 있다

funcName(first:number, lastName="Smith") ⇒ default 매개변수는 타입 명시하지 않아도 타입 추론이 가능하다.

나머지 매개변수 Rest Parameters

컴파일러는 ... 생략 부호 뒤 인자 배열을 빌드하여 함수에서 사용할 수 있다.

나머지 매개변수는 수를 무한으로 취급한다. 아무것도 없어도 된다.

객체 지향 프로그래밍 OOP

프로그램을 객체의 모임으로 파악하려는 프로그래밍 패러다임

객체는 서로 메시지를 주고 받고, 데이터를 처리할 수 있다.

  • 장점
    • 프로그램을 유연하고 변경이 용이하게 만든다
    • 개발과 보수를 간편하게 만든다
    • 직관적 코드 분석이 가능해진다.

Class

  • 요소
    • 멤버 (아래 세 가지를 통칭하는 말)
    • 필드
    • 생성자
    • 메소드
  • 인스턴스 : new 연산자로 생성된 객체
  • this는 클래스를 가리켜 this. 을 통해 클래스의 멤버를 가리킬 수 있다.

접근 제어자

  • 접근을 제한하기 위해 사용
  • public > protected > private
  1. public

    자유롭게 접근할 수 있다.

    기본으로 선언되는 접근 제어자

  2. private

    외부에서의 접근을 막는다.

  3. protected

    해당 클래스와 이를 상속받은 클래스 외의 접근을 막는다.

    ⭐️ 상속

    • 클래스를 확장해서 사용할 수 있다
    • 파생된 클래스를 하위(subclass), 기초 클래스를 상위 클래스(superclass)라고 한다.

이외 선언시 사용 가능한 것들

  1. getters & setters

    멤버를 private으로 설정하고, 속성값을 접근하여 읽고 수정하는 것은 getter/setter 함수를 사용한다.

    직접 수정하면 데이터 무결성이 깨질 수 있기에 캡슐화를 하는 것이다.

    해당 함수로 멤버 접근시에 조건을 추가할 수 있어 세밀한 제어가 가능하다.

  2. readonly

    읽기기만 가능한 속성을 선언. 수정 불가.

    선언 혹은 생성자에서 값을 한번 설정하고 나면 수정이 불가하다.

  3. static

    클래스 자체에서 보이는 전역 멤버를 생성

    • 전역 멤버 : 객체마다 할당되는 것이 아닌 클래스로 만들어진 모든 객체가 공유하는 멤버

    범용적으로 사용되는 값에 설정된다.

    클래스명. 을 앞에 붙여 static 멤버에 접근할 수 있다.

    JS에서는 지원되지 않는다.

추상 클래스

다른 클래스들이 파생될 수 있는 기초 클래스로 인스턴스화는 불가능하다.

abstract 키워드를 이용해 추상 클래스, 추상 메소드를 정의할 수 있다.

추상 메소드는 클래스에 구현되지 않고, 파생된 클래스에서 구현해야지 사용 가능하다.

  • Template Method Pattern
    • 프로그램의 일부분을 서브 클래스로 캡슐화해 전체 구조를 바꾸지 않고 특정 단계의 기능을 바꾸는 것
    • 전체(공통?)적인 알고리즘은 상위에서 구현하고, 다른 점은 하위클래스에서 구현
    • 메소드의 코드 중복을 최소화할 수 있다.

Interface

변수, 함수, 클래스에 타입체크를 위해 사용된다.

인스턴스화가 불가하고, 모든 메소드가 추상 메소드이다.

abstract 키워드는 사용하지 않는다.

☑️  사용하는 이유?

타입의 이름을 짓고, 그 안에서 규칙을 정의할 수 있다.

외부에서 사용하는 코드의 규칙을 정의하는 강력한 방법이다.

  • 객체의 스펙 : 속성과 속성의 타입
  • 함수의 파라미터
  • 함수의 스펙 : 파라미터, 반환 타입 등
  • 배열과 객체에 접근하는 방식
  • 클래스 → 에서 이용한다.
interface Person{
	name: string
}
function sayName(obj:Person){ // 함수 매개변수의 프로퍼티를 정의할 수 있다.
}

Properties

컴파일러는 프로퍼티의 두 가지 요소를 검사한다

  1. 필수 요소 프로퍼티의 유무
  2. 프로퍼티 타입

Optional Properties

  • 선언시 이름 끝에 ?를 붙여 표시한다.
  • 인터페이스에 속하지 않는 프로퍼티의 사용을 방지
  • 사용 가능한 프로퍼티를 기술시 사용
  • 몇개의 프로퍼티만 채워서 함수에 전달하는 option bags 패턴에 유용한다.

Readonly properties

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

⚡️ readonly vs const

공통 : 생성 후 배열을 변경하지 않음을 보장한다.

차이 : const는 변수에 readonly는 프로퍼티에 이용된다.

interface types

함수, 클래스에서 사용 가능하다.

function type

객체가 가질 수 있는 넓은 범위의 형태를 기술한다. 객체 기술 외에도 함수 타입을 설명한다.

인자와 반환 값의 타입을 정의한다.

interface SearchFunc{
	(source:string, substring:string):boolean
}
let mySearch: SearchFunc = function(src,sub){ // src - source, sub - substring
	~
}

class type

특정 통신 프로토콜을 충족하도록 명시적으로 강제 한다.

특정 계약을 충족하도록 명시적으로 강제하는 것

interface Animal{
	makeSound():void
}
class Dog implements Animal -> makesound를 구현해야한다.

인터페이스 간의 확장이 가능하다

interface Dog extends Animal{
	// 멤버 추가 가능
}

hybrid type

자스의 유연하고 동적인 타입 특성에 따라 인터페이스 역시 여러가지 타입을 조합할 수 있다.

함수 타입이면서 객체 타입을 정의할 수 있는 인터페이스도 구현 가능

interface Counter{
	(start:number):string
	interval : number
	reset():void
}

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

Strategy Pattern

객체가 할 수 있는 행위를 전략으로 만들어 두고, 동적으로 행위의 수정이 필요한 경우 전략을 바꾸는 것으로 수정이 가능하도록 만든 패턴

→ 다른 행위가 가능하도록 만드는 것

예시 : 자판기 결제 방법을 현금 결제와 카드 결제 두개로 둘 때

→ 메소드 수정시 OOP 설계 원칙을 위배한다. 수정은 닫혀있어야 한다.

상위 인터페이스를 구현한 각각의 역할을 하는 클래스를 구현해둔다.

vendingmachine에서 payment 부분의 매개변수를 상위 인터페이스 타입으로 두고,

구현시 각 상황에 맞춰 각각 역할을 하는 객체를 전달한다.

Generic

data type을 일반화하는 것이다. 식별자를 써서 정해지지 않은 타입을 표시한다.

정적 type 언어는 클래스나 함수를 정의시 type을 선언해야 한다.

→ 이를 보완한 것으로 코드가 수행될 때, 생성 시점에 타입을 명시한다.

사용하는 이유?

  • 재사용성이 높은 함수와 클래스를 생성할 수 있다. 한번의 선언으로 다양한 타입에 재사용할 수 있다.
  • 오류를 쉽게 포착할 수 있다. any는 컴파일 시 타입을 체크하지 않아 오류 파악이 어렵다. 컴파일 시 컴파일러가 오류를 찾지 못한다. 타입이 체크되지 않으면 관련 메소드의 힌트를 사용할 수 없다.

사용

function sort<T>(items:T[]):T[]{
	return items.sort()
}
class Queue<T>{
	protected data:Array<T>=[]
}

Union Type

| 를 사용해 두 개 이상의 타입을 선언하는 방식

vs Generic : Union은 공통된 메소드만 사용할 수 있다. 하나의 타입이 아닌 선언된 union 타입으로 리턴된다.

제약조건 (Constraints / keyof)

원하지 않는 속성에 접근하는 것을 막기 위해 사용

Constraints

특정 타입들로만 동작하는 제네릭 함수를 만들 때 사용한다.

벗어나는 타입을 선언하면 에러가 발생한다.

const prinMsg = <T extends string|number>(message:T):T =>{

→ string과 number만 매개변수로 들어 올 수 있다.

Keyof

두 객체를 비교시 사용한다.

const getProperty = <T extends object, U extends keyof T>(obj:T,key:U)=> {}

getProperty({a:1,b:2,c:3},"a"); 
getProperty({a:1,b:2,c:3},"z"); // 에러 발생, T에 포함되지 않음

Factory Patterns

객체를 생성하는 인터페이스만 미리 정의

인스턴스를 만들 클래스의 결정은 서브 클래스가 내리는 패턴

여러 서브 클래스를 가진 슈퍼클래스가 입력에 따라 하나의 서브 클래스의 인스턴스를 반환

interface Car

class Bus implements Car
class Taxi implements Car
class Suv implements Car

class CarFactory{
	static getInstace<T extends Car>(type:{new():T}):T{
		return new type();
	}
} 
profile
터벅터벅 개발(은좋은)자 로그

0개의 댓글

관련 채용 정보