동적 타입을 정적으로 선언 가능하다. (미리 지정할 수 있음, 실행 되고 데이터를 본 뒤에 결정되는 것이 아님)
⇒ 오류를 코드 작성시 포착할 수 있다. JS는 실행하고 나서 알 수 있다.
타입 유추를 통한 타입 제어가 가능하다.
⇒ 매개변수를 통해 함수 반환 타입을 명시하지 않아도 유추하여 제어해줌
컴파일 시점에 오류를 포착할 수 있다.
추가 코드 기능이 있다
실제 값을 저장하는 자료형
내장 함수를 사용 가능함 ⇒ JS의 처리 방식덕에 가능
Object 형식의 타입
메모리에 값을 주소로 저장! 주소와 일치하는 값을 출력
{ }
, 배열 [ ]
let arr:number[]
let arr:Array<number>
개발자 편의를 위해 추가 제공
let arr:[string,number]=["HI",6]
enum Car {BUS,TAXI,SUV};
→ 값이 0부터 할당됨항상 오류 발생하거나 절대 반환하지 않는 반환 타입
function neverEnd():never{
while(true){}
// throw Error('error') -> 가능
// break -> 하면 에러 발생, 함수가 종료되므로
}
공통 타입 변환을 용이하게 하기 위해 제공한다.
전역으로 사용 가능하다
다른 객체들에 일반적으로 적용 가능한 연산을 모두 지원하는 객체
☑️ 조건
⇒ 함수는 조건을 모두 충족하여 일급객체이다.
함수 선언식
function world(name){
return `hello ${name}`;
}
함수 표현식
let world =function(name){
return `hello ${name};
}
화살표 함수 표현식 Arrow Function
let world =(name)=>{
return `hello ${name};
}
단축형 화살표 함수 표현식
let world = (name) => `hello ${name}`
함수 생성자 ⇒ 사용이 권장되지 않는다
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
}
함수에 주어진 인자의 수는 기대하는 매개변수의 수와 일치해야한다.
JS ⇒ 모든 매개변수가 선택적으로 들어오고, 없다면 undefined가 된다.
TS ⇒ 선택적 매개변수를 ?로서 이용할 수 있다
TS에서는 값을 제공하지 않거나 undefined를 했을 때 매개변수 값을 할당 해둘 수 있다
funcName(first:number, lastName="Smith")
⇒ default 매개변수는 타입 명시하지 않아도 타입 추론이 가능하다.
컴파일러는 ... 생략 부호 뒤 인자 배열을 빌드하여 함수에서 사용할 수 있다.
나머지 매개변수는 수를 무한으로 취급한다. 아무것도 없어도 된다.
프로그램을 객체의 모임으로 파악하려는 프로그래밍 패러다임
객체는 서로 메시지를 주고 받고, 데이터를 처리할 수 있다.
this.
을 통해 클래스의 멤버를 가리킬 수 있다.public
자유롭게 접근할 수 있다.
기본으로 선언되는 접근 제어자
private
외부에서의 접근을 막는다.
protected
해당 클래스와 이를 상속받은 클래스 외의 접근을 막는다.
⭐️ 상속
getters & setters
멤버를 private으로 설정하고, 속성값을 접근하여 읽고 수정하는 것은 getter/setter 함수를 사용한다.
직접 수정하면 데이터 무결성이 깨질 수 있기에 캡슐화를 하는 것이다.
해당 함수로 멤버 접근시에 조건을 추가할 수 있어 세밀한 제어가 가능하다.
readonly
읽기기만 가능한 속성을 선언. 수정 불가.
선언 혹은 생성자에서 값을 한번 설정하고 나면 수정이 불가하다.
static
클래스 자체에서 보이는 전역 멤버를 생성
범용적으로 사용되는 값에 설정된다.
클래스명.
을 앞에 붙여 static 멤버에 접근할 수 있다.
JS에서는 지원되지 않는다.
다른 클래스들이 파생될 수 있는 기초 클래스로 인스턴스화는 불가능하다.
abstract 키워드를 이용해 추상 클래스, 추상 메소드를 정의할 수 있다.
추상 메소드는 클래스에 구현되지 않고, 파생된 클래스에서 구현해야지 사용 가능하다.
변수, 함수, 클래스에 타입체크를 위해 사용된다.
인스턴스화가 불가하고, 모든 메소드가 추상 메소드이다.
abstract 키워드는 사용하지 않는다.
☑️ 사용하는 이유?
타입의 이름을 짓고, 그 안에서 규칙을 정의할 수 있다.
외부에서 사용하는 코드의 규칙을 정의하는 강력한 방법이다.
interface Person{
name: string
}
function sayName(obj:Person){ // 함수 매개변수의 프로퍼티를 정의할 수 있다.
}
컴파일러는 프로퍼티의 두 가지 요소를 검사한다
⚡️ readonly vs const
공통 : 생성 후 배열을 변경하지 않음을 보장한다.
차이 : const는 변수에 readonly는 프로퍼티에 이용된다.
함수, 클래스에서 사용 가능하다.
객체가 가질 수 있는 넓은 범위의 형태를 기술한다. 객체 기술 외에도 함수 타입을 설명한다.
인자와 반환 값의 타입을 정의한다.
interface SearchFunc{
(source:string, substring:string):boolean
}
let mySearch: SearchFunc = function(src,sub){ // src - source, sub - substring
~
}
특정 통신 프로토콜을 충족하도록 명시적으로 강제 한다.
특정 계약을 충족하도록 명시적으로 강제하는 것
interface Animal{
makeSound():void
}
class Dog implements Animal -> makesound를 구현해야한다.
인터페이스 간의 확장이 가능하다
interface Dog extends Animal{
// 멤버 추가 가능
}
자스의 유연하고 동적인 타입 특성에 따라 인터페이스 역시 여러가지 타입을 조합할 수 있다.
함수 타입이면서 객체 타입을 정의할 수 있는 인터페이스도 구현 가능
interface Counter{
(start:number):string
interval : number
reset():void
}
function getCounter():Counter{
let counter = function(start:number) {} as Counter
counter.interval = 123
return counter
}
객체가 할 수 있는 행위를 전략으로 만들어 두고, 동적으로 행위의 수정이 필요한 경우 전략을 바꾸는 것으로 수정이 가능하도록 만든 패턴
→ 다른 행위가 가능하도록 만드는 것
예시 : 자판기 결제 방법을 현금 결제와 카드 결제 두개로 둘 때
→ 메소드 수정시 OOP 설계 원칙을 위배한다. 수정은 닫혀있어야 한다.
상위 인터페이스를 구현한 각각의 역할을 하는 클래스를 구현해둔다.
vendingmachine에서 payment 부분의 매개변수를 상위 인터페이스 타입으로 두고,
구현시 각 상황에 맞춰 각각 역할을 하는 객체를 전달한다.
data type을 일반화하는 것이다. 식별자를 써서 정해지지 않은 타입을 표시한다.
정적 type 언어는 클래스나 함수를 정의시 type을 선언해야 한다.
→ 이를 보완한 것으로 코드가 수행될 때, 생성 시점에 타입을 명시한다.
function sort<T>(items:T[]):T[]{
return items.sort()
}
class Queue<T>{
protected data:Array<T>=[]
}
|
를 사용해 두 개 이상의 타입을 선언하는 방식
vs Generic : Union은 공통된 메소드만 사용할 수 있다. 하나의 타입이 아닌 선언된 union 타입으로 리턴된다.
원하지 않는 속성에 접근하는 것을 막기 위해 사용
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에 포함되지 않음
객체를 생성하는 인터페이스만 미리 정의
인스턴스를 만들 클래스의 결정은 서브 클래스가 내리는 패턴
여러 서브 클래스를 가진 슈퍼클래스가 입력에 따라 하나의 서브 클래스의 인스턴스를 반환
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();
}
}