타입을 결정하는 시점에 따라 타입을 분류
정적 타입(static type)
모든 변수의 타입이 컴파일 타임에 결정. 코드 수준에서 타입을 명시해줘야 함
번거롭지만 컴파일타임에 타입에러를 발견할 수 있기 때문에 프로그램의 안정성을 보장
동적 타입(dynamic type)
변수 타입이 런타임에서 결정됨. 개발자가 직접 타입 정의 X.
암묵적 타입 변환
개발자가 의도적으로 타입을 명시하거나 바꾸지 않았는데도 컴파일러 또는 엔진 등에 의해서 런타임에 타입이 자동으로 변경되는 것
강타입
서로 다른 타입을 갖는 값끼리 연산 시도하면 에러 발생
ex) 파이썬
, 루비
, 타입스크립트
약타입
서로 다른 타입을 갖는 값끼리 연산 시도하면 내부적으로 판단해서 특정 값의 타입을 변환하여 연산을 수행
ex) c++
, 자바
, 자바스크립트
일반적인 컴파일의 의미
사람이 이해할 수 있는 코드를 컴퓨터가 이해할 수 있는 기계어로 바꿔주는 과정
c#,Java(고수준 언어) -> 컴퓨터가 해석할 수 있는 바이너리 코드(저수준 언어)
but, 타입스크립트의 컴파일 결과물은 자바스크립트 파일임
왜냐 타입스크립트는 사람이 이해하기 쉬운 방식으로 코드를 작성하려고 나온게 아니기 때문임
JS의 컴파일 타임에 런타임 에러를 사전에 잡아내기 위한 것임.
-> 타입스크립트를 컴파일하면 타입이 모두 제거된 JS소스코드만 남게됨
타입스크립트는 구조로 타입을 구분함. 이것을 구조적 타이핑이라고 함
구조적 서브 타이핑
타입스크립트의 타입은 값의 집합으로 생각할 수 있음.
타입은 단지 집합에 포함되는 값이고 특정 값은 많은 집합에 포함될 수 있다.
따라서 타입스크립트에서는 특정 값이 string 또는 number 타입을 동시에 가질 수 있음.
이런 TS의 타입 시스템을 지탱하고 있는 개념이 바로 구조적 서브 타이핑임
: 객체가 가지고 있는 속성을 바탕으로 타입을 구분하는 것. 이름이 다른 객체라도 속성이 동일하다면 TS는 서로 호환이 가능한 동일한 타입으로 여김
interface Pet {
name: string
}
interface Cat {
name: string
age: number
}
let pet: Pet;
let cat: Cat = { name: "Zag", age: 2 };
// ✅ OK
pet = cat;
Cat은 Pet과 다른 타입으로 선언. 하지만 Pet이 가지고 있는 name속성을 가지고 있음.
따라서 Cat타입으로 선언한 cat을 Pet타입으로도 선언한 pet에 할당 가능
JS - 덕타이핑
- 런타임에 검사
TS - 구조적 타이핑
- 컴파일타임에 검사
두 방식 모두 객체가 가진 속성을 기반으로 타입을 검사
필요에 따라 타입 선언 생략을 허용하는 방식
function add(x, y) {
return x + y;
}
// 위 코드는 아래와 같이 암시적 타입 변환이 일어난다.
function add(x: any, y: any): any
그러나 TS는 컴파일타임에 프로그램의 모든 타입을 알고 있을 때 최상의 결과를 보여줌
그리하여, TS컴파일옵션에 noImplicitAny = true
로 설정하는 것이 좋음
값은 프로그램이 처리하기 위해 메모리에 저장하는 모든 데이터
객체 역시 값. JS에서는 함수도 값. 모든 것이 객체인 언어이기 때문에 런타임에 객체로 변환됨
ex)
const goWork = function (developer) {
console.log(`tired ${developer}`);
}
JS대신 타입스크립트에서는 변수,매개변수,객체 속성 등에 : type 형태로 타입을 명시함
ex) const a:number = 223
type
,interface
키워드로도 가능
값 공간과 타입 공간의 이름은 서로 충돌하지 않기 때문에 타입과 변수를 같은 이름으로 정의할 수 있음
타입스크립트 문법인 type으로 선언한 내용은 JS 런타임에서 제거되기 때문
함수의 매개변수처럼 여러개의 심볼이 함께 쓰인다면 타입과 값을 명확하게 구분해야 함
TS는 개발자가 작성한 코드 문맥을 파악해서 스스로 값,타입을 해석 -> 구분해서 작성해야함
ex)
function email(options: { person: Person; subject: string; body: string }) {}
타입스크립트에서 구조분해할당하면 Person
과 string
이 값의 관점에서 해석됨.
그니까 Person
,string
이 값 공간에 있는 것으로 해석한다는 거임.
개발자의 의도는 매개변수 객체의 속성인 perosn
을 Person타입, subject
,body
는 string타입으로 설정해서 제한하는 건데,Person과 string이 값의 관점에서 해석해버림.
그래서 값과 타입을 구분해서 작성해야됨
like this
function email({
person,
subject,
body
}:{
person: Person;
subject:string;
body:string;
}){
~~~~~~
}
class나 enum은 값으로도 타입으로도 사용됨
ex)
const me: Developer = new Developer("zig","frontend")
->타입 ->값
enum을 자주 사용하는 팀도 있고 아닌 팀들도 있는 듯!...
.
.
.
출처: 우아한 타입스크립트 with 리엑트