타입스크립트는 기본적으로 타입 추론을 제공합니다.
타입에 대해 명시하지 않으면 TS 자체적으로 판단하고 명시하죠
하지만 추론이란 어디서 부터 어디까지를 기준으로 두는것인지 애매하기 때문에
tsconfig.json
파일에서 설정할수 있도록 만들었습니다.
협업을 하면 구현자 와 사용자가 있을겁니다.
만약 구현자가 함수를 추론위주로 구현하면 사용자가 의도치않게 다른타입의 인자를 넣을수 있습니다.
따라서 그런 일을 방지하고자 tsconfig.json 에는 구현자에게 오류를 알려주는 여러 옵션들이 존재합니다.
아래 옵션들은 기본적으로
true
로 설정되있습니다.
any 타입으로 암시한 표현식과 선언에 오류를 발생시킵니다.
매개변수에 타입을 명시하지 않은 경우입니다.
a 는 현재 any 라는 타입을 추론하고 있습니다.
"noImplicitAny": true
로 정했을 경우
function num(a) {
return a * 30
}
console.log(num(2)); // 60
console.log("hello"); // error
컴파일 단계에서 오류가 발생합니다.
즉 noImplicitAny
옵션을 켰을때 타입스크립트는 사용자에게
"any 면 직접 any를 명시하거나 다른타입을 명시해!" 라고 오류를 출력하는겁니다.
function num(a:number) {
return a * 30
}
console.log(num(2)); //60
console.log("hello"); // 오류
타입을 명시했다고 가정합시다
매개변수에는 타입을 명시했지만 리턴값에는 명시하지 않았습니다.
그러면 타입스크립트는 자동적으로 number | undefined 두가지를 리턴합니다.
왜냐하면 null 과 undefined은 모든 타입의 하위 타입 이기 때문이죠
function num(a:number){ //function num(a: number): number | undefined
if(a>0){
return a * 30;
}
}
console.log(num(2));
console.log(num(-5)+5); // NAN 인데 오류 출력을 안함
그런데 문제가 있습니다. a 에 음수를 집어넣으면 undefined 이 return 되고
여기에 5를 더하기 때문에 NAN 을 반환합니다.
리턴값에 넘버 하나만 명시하면 어떻게 될까요?
function num(a:number):number{
if(a>0){
return a * 30;
}
}
console.log(num(-5)+5); // NAN 인데 오류 출력을 안함
리턴값을 number 만 명시해도 타입스크립트는 undefined 를 number 안에 포함시키기 때문에
오류 출력을 하지 않습니다.
이럴땐 strictNullChecks
를 true
로 설정하면
모든 타입에 null 과 undefined 제거가 되고 오류를 발생 시킵니다.
프로그램 언어는 여러가지 타입시스템이 있습니다.
구조적 자료형 체계
라고도 불리는 structural type system
은
타입스크립트의 자료형 체계이기도 합니다. 이름이 달라도 구조가 같으면 서로 같은것으로 판단합니다. ex)(OCaml Go TypeScript Scala)
명목적 자료형 체계
라고 불리는 nominal type system
은
상속과 같은 선언을 하지 않으면 구조가 일치해도 다른 타입이라고 판단합니다.
대표적으로는 C++, C#, Java, 오브젝티브-C, Delphi, Swift, Rust
등이 있습니다.
duck typing은 structural type system 과 거의 비슷하지만
duck typing 은 동적 언어
에서 structural type system 는 정적 언어
라는 차이가 있습니다.
타입스크립트는 큰 타입에 작은 타입을 할당할수 있습니다. 여기서 작은 타입은 서브타입
이라고 합니다.
let subtype : 1 =1;
let supertype :number=subtype
subtype = supertype //오류 발생
supertype : number
,subtype : 1
입니다. 넘버란 타입에 1은 할당이 가능합니다.
하지만 숫자 1에 number 란 타입은 할당이 불가능하죠
let subtype :[number, number] = [1,2]
let supertype:number[] = subtype
subtype = supertype; // 오류 발생
마찬가지로 튜플은 배열의 서브 타입입니다. 배열에는 튜플을 할당할수 있지만 반대는 불가능합니다.
이번에는 any
를 살펴보겠습니다.
any 어떠한 것도 받을수 있는 타입입니다. 따라서 가장 상위타입이죠
any 는 어떠한것도 받을수 있지만 반대로도 가능합니다.
let subtype : number =1;
let supertype:any = subtype;
subtype = supertype //오류 없음
any 는 특별한 타입이기 때문에 1이란 타입에 any를 할당하는것도 가능합니다 😨
any 같은 특별한 경우를 제외하면 대부분의 슈퍼타입은 서브타입에 할당이 불가능합니다.