타입스크립트는 type error와 runtime error로부터 개발자를 보호한다.
console.log([1,2,3] + true // 1,2,3true
JS는 위의 예시처럼 type에 대해 매우 관대한 모습이었고 어떻게든 개발자에게 에러를 보여주지 않기위해 노력하는것 같았다. 또한 사용자의 브라우저에서 생기는 런타임 에러를 미리 방지할 수 있는 수단이 부족했다.
실제 사례로...
개발자 친구가 null + null
이 무엇인지 아느냐는 질문을 받았을 때 당연히 null
이겠지 라고 생각했던 나는 아래와 같은 충격을 받았었다.
console.log(null + null) // 0
console.log(null + 1) // 1
console.log(null + true) //1
개인 프로젝트를 진행하면서도 프론트엔드 코드에서 뭔가 오류가 생기면 서버에서 보내주는 데이터의 타입을 먼저 검증해보곤 했었다. 1 인지 '1' 인지
타입에 대한 확신이 없었다는 말이다.
물론 내 개발실력이 모자라서 그런것일 가능성도 매우 높지만....
아무튼 위와 같은 계기로 TS를 배워야겠다는 생각을 처음 하게되었고 공부를 시작하게 되었다.
- Implicit : 타입스크립트가 타입을 추론
- Explicit : 타입을 명시
- Optional : 속성을 선택적으로 부여할 때 ( 지정한 타입 or undefined )
- Alias : 타입을 재사용
- in Function : 입력과 출력의 타입 설정
/* Implicit */
let a = "hello"; // TS 가 a 변수의 type을 string으로 추론함
a = "hi"; // no error
a = 1 ; // error
/* explicit */
let a : string = "hello"; // 변수와 함께 타입 지정
let b : number[] = [1, 2, 3]; // 숫자들의 배열
b.push("1"); // error
let c : string[] = [1, 2]; //error
let d : bollean = true;
/* optional */
let user1 : { name : string, age? : number } = {
name : "funco",
age : 32
} // ? 이 붙으면 선택적 속성이다.
let user2 : { name : string, age? : number } = {
name : "nugu"
} // no error
/* Alias */
type User = { name : string, age? : number }
let user1 : User = {
name : "funco",
age : 32
} // no error -> 타입 재사용 & 코드를 줄이기 위한 나은 방법
/* function argument & return type */
function createUser(name : string) : User {
return {
name : name // same as just `name`
}
} // name 이라는 string 변수를 입력받아 User 타입을 리턴한다.
const funco = createUser("funco"); // typeof funco = User
func0.age = 32 // no error
const createUser2 = (name : string) : User => ({name}) // 위와 동일
- Readonly
type User = { readonly name : string, age? : number };
const createUser2 = (name : string) : User => ({name});
const funco = createUser2("funco");
funco.age = 32; // no error
funco.name = "nugu"; // error
- 항상 정해진 길이의 배열과 요소의 타입, 순서를 지정
const user : [string, number, boolean] = ["funco", 20, false]; // no error
user[0] = true; // error
const user : readonly [string, number, boolean] = ["funco", 20, false];
user[0] = "lalala"; // error
- 타입스크립트로부터 해방됨 (사용을 지양하는게 좋을까...?)
const a : any[] = [1,2,3,4]; // no error
const b : any = true; // no error
a + b // no error
- 변수를 사용하기 전에 type check를 선행하도록 유도한다
let a : unknown;
let b = a + 1; // error, because TS doesn't know type of `a`
if(typeof a === 'number'){ let b = a + 1 } // no error
let c = a.toUpperCase(); // error, because type of `a` isn't string
if(typeof a === 'string'){ let c = a.toUpperCase() } // no error
- 아무것도 return하지 않는 함수를 대상으로 사용
function hello () {console.log("hello world") }; // typeof hello = void
오류, 일치조건 없음 등의 이유로 함수가 절대 아무것도 리턴하지 않음
function hello( name : string | bollean){
if(typeof name === "string"){
return name // typeof name is " string "
} else if ( typeof name === "bollean") {
return name // typeof name is " bollean "
} else {
return name // typeof name is " never ", because this line never run
}
}