TypeScript (2) 어떻게 쓰는 걸까?

2020. 11. 10. 19:39Project-Review

이번 장에서는 타입스크립트에 대해 완벽한 이해가 있는 상황이 아니었기 때문에, 사용법과 에시륻 들면서 써보겠다.

 

1. 추론

자바스크립트의 원시타입으로 String, Number, Object를 들 수 있다. 그렇지만, 일관된 타입을 사용하였는지 알기 해 필요한 것이 타입스크립트이다. ts파일을 만들어 다음과 같이 String을 변수에 할당하고, 변수에 마우스를 올려보면 주석과 같은 안내가 뜬다.

 

var example = 'Let's learn TypeScript!';
//var example:string

//물론 아래와 같이 먼저 정의해줄 수 있다.
var str:string;
str = "Good!"

 

example 변수는 string타입이라는 뜻인데, 이 말은 이제 example은 string타입으로 사용할 수 있다는 뜻이다. 이렇게 자동으로 타입을 선언해주는 것을 추론이라고 한다. 그리고 타입이 선언되면 이제 그 변수는 그 타입안에서만 변경할 수 있다. 

 

example = 'hi' //해당 코드는 string타입을 재할당 해준 것이므로 가능하다.
exmaple = 26 //26는 number이므로 할당이 불가능하다!

 

이렇게 타입을 선언하고 사용하는 방법을 '정적 타이핑'이라고 하고 이 방법은 처음엔 번거로울 수 있지만, 오류의 갯수를 상당히 줄일 수 있다!

 

2. 타입 정의

이렇게 자동으로 정의를 해주는 것은 편리하지만, 우리가 직접 타입을 만들어 제공해 줄 수 있다. 객체를 예로 들자면, 우리는 객체안에 이름, 나이가 무조건 있어야하는 User 객체를 만든다고 생각해보자. 그럴 경우 우리는 interface를 만들어 줄 수 있다. Interface란, 쉽게 말해 string과 같은 원래 있는 타입을 제공해주는 것이 아닌, 우리가 직접 커스터마이징을 해서 준다고 생각하면 편하다. 그래서 다음과 같은 객체를 만들어 줄 수 있다.

 

interface User {
    name:string
    age:number
}

const user:User = {
    name : "mj",
    age : 26
}

 

만약 선언한 Interface외의 값이나 타입이 들어오는 경우는 다음과 같이 에러를 출력한다. 처음 타입스크립트를 쓰면 멍해지는 에러타입이므로 숙지해두자!

 

// 1. key type이 잘못 선언된 경우
const user:User = {
    name : "mj",
    age : 'hi' //Type 'string' is not assignable to type 'number'
}

// 2. 필요한 값이 부족한 경우
const user:User = { //Property 'age' is missing in type '{ name: string; }' but required in type 'User'
	name : "mj"
}

// 3. 선언된 값 외에 들어간 경우
const user:User = {
    name : "mj",
    age : 26,
    gender : "male" 
    //Type '{ name: string; age: number; gender: string; }' is not assignable to type 'User'.
    Object literal may only specify known properties, and 'gender' does not exist in type 'User'.
} 

 

배열이나 객체는 어떻게 할 수 있을까? 의외로 간단하다. 만약 위의 User타입만을 가진 배열을 만들고 싶다면 아래와 같이 하면 된다.

 

//객체를 직접 만들어 넣어도 되고, 위에서 만든 user를 직접 넣어도 된다. 
//아래의 뜻은 arr의 타입으로 User타입이 들어있는 배열을 선언한다는 뜻이다.
var arr:User[] = [{name : "minjae", age : 25} , user]

//더 밑에서 말하겠지만, Generic 방식으로 이렇게도 쓸 수 있다.
var arr:Array<User> = [{name : "minjae", age : 25} , user]

 

 

3.  객체지향 or 함수에 타입을 줘보자

 

타입스크립트는 객체지향이나 함수에도 적용을 시킬 수 있다. 그래서 input/output값이 원하는 타입인지 확인하기가 용이하다.

 

class UserList {

    name:string;
    age:number

    constructor(name:string,age:number){
        this.name = name;
        this.age = age;
    }

}

const newUser = new UserList('mj',26);

const makeUserList = (input_name:string,input_age:number):User => {
    let obj = {
        name : input_name,
        age : input_age
    };

    return obj;
}

const deleteUser = (origin_user:User) => {
    //..
}

 

4. Composing Type

 

user에 User 타입을 주면서 나는 성별을 넣고 싶었다. 그런데 성별은 'male'아니면 'female'이므로 string으로 판별하기는 애매하다. 그럴 때 쓸 수 있는 것이 타입을 간단한 것들로 결합해서 사용할 수 있는 Union이라는 방법이 있다. User가 이제 이름,나이,성별을 갖도록 새롭게 만들어보자.

 

interface newUser {
    name:string
    age:number
    gender: "female" | "male"
}

const new_type_user:newUser = {
    name : 'mj',
    age : 26,
    gender : "male"
}

 

 

Union이라는 방법 외에도 Generics라는 방법도 있는데, 변수의 타입을 정의해주는 것이다. 위의 예시에서 배열에 Array<User>를 보여준 적이 있는데, 이 방법을 얘기한다. 그러면 User[]와의 차이점을 물을 수 있는데, 큰 차이점으로 변수의 타입을 나중에 선언할 수 있다. 즉, 어떤 타입이 들어올지 경우에 따라 다르다면 다음과 같이 쓸 수 있다.

 

interface Backpack<Type> {
    add: (obj: Type) => void;
    get: () => Type;
}
//나중에 Type 위치에 원하는 타입을 선언하여 사용하면 된다

 

대략적으로, 타입스크립트 공식문서에 기반해 사용법을 알아보았다. 직접적인 사용방법은 다양하므로 많은 방법으로 실험을 해 보는 것도 좋을 것 같다.