________________________________________________________________________
TypeScript 에는 그 외에 어떤 타입들이 존재하는가 -1-
< 선택적 타입(=optional type) >
< 별칭 타입 (=Alias type) >
< 함수의 인자값의 타입을 명시하는 법 >
<함수의 return 값의 타입을 지정하는 법 >
Number, string, boolean, array, object 외에 어떤 타입들이 존재하는가.
우선, 여태까지 살펴봤던 기본적인 타입들은 다음과 같아.
——
let a : number = 1;
let b : string = "aaa";
let c : boolean = false;
let d : number[] = [1];
let e : string[] = ["aaa"];
let f : boolean[] = [false];
——
=> 만약 d, e, f 의 변수에 할당된 값들이 배열에 감싸져 있지 않으면 빨간줄이 그이겠지?
물론, 다음 처럼 표기할 수도 있어.
——
let a = 1;
let b = "aaa";
let c = false;
——
=> 때로는, 굳이 타입을 명시할 필요가 없을 수도 있어.
어떤 때에는 타입스크립트가 자동으로 타입을 추론하게 하는 것이 좋아.
위의 경우에서도 타입스크립트는 마치 타입이 명시가 된 것 마냥 타입을 추론하며,
let a 의 타입은 number 라고 스스로 정의할 거야.
이 상태에서 a 에 숫자나 불린을 넣으려 한다면 당연히 버그가 발생 하겠지.
가능한, 굳이 타입을 명시할 필요가 없다면 타입스크립트가 알아서 타입을 추론하도록 놔두는 편이 좋아.
1.
________________________________
< optional 타입 >
한 가지 가정을 하자. 다음과 같은 객체가 있어.
——
const player = {
name: "minsoo"
}
——
=> 플레이어가 다수 존재하는데, 모든 플레이어들은 name 이라는 속성을 가지지만, 그중 몇몇 만이 age 라는 속성을 가진다고 쳐.
이것을 타입스크립트에서 어떻게 쓸 수 있을까.
일단 기본적으로 player 라는 변수에 대해 타입을 명시해보자.
——
const player : {} = {}
——
=> 이와 같은 형태가 되겠지? Player 는 {} 라는 객체 타입을 가지게 된다, 라고 명시한 거야.
그럼 명시된 {} 라는 타입 안에 내용을 추가해보자.
——
const player : {
name: string,
age?: number
}= {
name: "minsoo"
}
——
=> 옵셔널 문법을 적용했어. 만약 age 옆에 ? 가 없었다면 타입스크립트는 오류를 띄웠을 거야.
“ 야, 너 분명 타입을 명시할 때에는 age 를 넣어놨는데, 실제로 할당된 객체에는 age 프로퍼티가 없어! “
라고 호소하면서.
허나 age? 가 된다면? 즉 age 라는 프로퍼티가 존재할 경우, 해당 변수의 타입은 number 이다, 라고 말해준 거지.
이로서 player 들은 모두 name 을 갖지만, age는 경우에 따라 가지거나 가지지 않거나 모두를 커버할 수 있게 되었어.
위의 상태에서 player 에 마우스를 갖다 대면 어떤 문구가 나올까?
——
const player: {
name: string;
age?: number | undefined;
}
——
=> age 는 number 이거나, undefined 일 수 있다. 라고 적혀 있어.
기존에 자바스크립트에서 우리가 했던 방식보다 더 나은 소통 방식을 타입스크립트가 채용하고 있어.
이 상태에서 player.age 를 불러 오면?
——
const player : {
name: string,
age?: number
}= {
name: "minsoo"
}
player.age ///// (property) age?: number | undefined
——
=> age 에 마우스를 가져가 보면, 위 처럼 문구가 출력되지.
만약 있을 수도 없을 수도 있는 age 로 연산을 하려 한다면?
——
const player : {
name: string,
age?: number
}= {
name: "minsoo"
}
player.age
if (player.age > 10) {
}
////
(property) age?: number | undefined
'player.age' is possibly 'undefined'.
——
=> 위처럼 age 는 undefined 일 수도 있다며 age 에 빨간 줄을 그어버려.
그렇다면, 다음처럼 코드를 개변한다면?
——
if (player.age && player.age > 10) {
}
——
위와 같이 조건을 하나 더 추가해준다면 더 이상 오류를 띄우지 않아. 빨간 줄도 사라졌어.
보호장치를 추가한 거지.
—
**** 이것이 optional parameter, 즉 “ 선택적 변수 “.
2.
_______________________________
< 만약 수많은 player 들이 존재한다면? Alias Type 을 사용해보자 >
이 경우, 우리는 별칭(=Alias) 타입을 생성할 수 있어.
알리아스 타입을 선언해 두면, 동일한 형태의 객체를 다수 생성할 때 코드량을 줄일 수 있어.
——
type Player = {
name: string,
age?: number
}
const minsoo : Player = {
name: "minsoo"
}
const msdou : Player = {
name: "dou",
age: 20
}
——
=>
마치 클래스가 인터페이스를 상속 받는 것 처럼,
마치 자바에서 변수의 타입이 인스턴스화 한 클래스의 이름으로 정해지는 것 처럼.
객체 리터럴 들이 Player 라는 타입을 “ 알리아스 타입 “ 으로서 가지고 있어.
조금 더 응용해 볼까?
——
type Age = number
type Player = {
name: string,
age?: Age
}
____
당연히 이런 식으로도 가능해. 객체에 만 적용되는게 아니라는 뜻.
물론, 이런 식으로 과하게 사용하는 건 좋지 않아. 걍 age?:number 라고 적으면 그만이잖아.
기본적으로 사용하는 타입들을 굳이 ‘별칭 타입’ 으로 지정할 필요는 없지.
3.
_______________________________
< Alias Type 을 사용해서 “함수”의 return 값의 타입을 지정하는 법 >
그럼 이번에는 함수 에도 이 타입스크립트의 타입 지정을 적용해 보자.
함수가 return 하는 타입이 뭔지를 알 수 있다면, 더욱 안정성 높은 코드를 짤 수 있을 거야.
아래는 함수에 alias 타입을 지정하는 방법.
——
type Player = {
name: string,
age?: number
}
function playerMaker (name: string) : Player {
return { name }
}
const minsoo = playerMaker("minsoo");
minsoo.age = 12
const playerMaker2 = (name: string) : Player => {
return { name }
}
const msdou = playerMaker2("msdou");
msdou.age = 20;
——
=> 기본적으로 : type 을 명시해주는 것은 다 똑같아.
일반 변수의 경우 그게 변수명 바로 옆에 이지만, 함수의 경우 () 바로 오른쪽에 명시를 해준다는 것.
playerMaker2 는 그냥 화살표 함수에도 같은 방식으로 적용된다 라는 걸 보여주고 있을 뿐.
*****
1 ~ 3번까지 우리는
< 선택적 타입(=optional type) >, < 별칭 타입 (=Alias type) >, < 함수의 인자값의 타입을 명시하는 법 >, <함수의 return 값의 타입을 지정하는 법 >
이렇게 크게 네 가지를 배웠어.
________________________________________________________________________
TypeScript 에는 그 외에 어떤 타입들이 존재하는가 -2-
< read only 타입 >
< 튜플 타입 >
< any 타입 >
1.
_______________________________
< 요소들을 “읽기 전용” 으로 만드는 “ readonly “ 타입 >
——
type Name = string;
type Age = number;
type Player = {
readonly name: Name,
age?: Age
}
——
=> readonly name: Name 이 부분.
readonly 를 객체의 프로퍼티 앞에 선언해 줌으로서,
더 이상 우리는 Player 타입의 name 이라는 프로퍼티를 외부에서 수정할 수 없게 된거야.
——
type Name = string;
type Age = number;
type Player = {
readonly name: Name,
age?: Age
}
function playerMaker (name: string) : Player {
return { name }
}
const minsoo = playerMaker("minsoo");
minsoo.age = 12
minsoo.name = "mmss"
——
=> 맨 마지막 줄에서 Player 타입을 가지고 있는 minsoo 라는 객체 변수의 name 속성을 수정하려고 시도하고 있어.
허나 곧바로 해당 코드에는 빨간 줄이 그이며 오류가 발생할 거라고 타입스크립트가 알려줄 거야.
왜? readonly name: Name 때문에, const minsoo = playerMaker("minsoo") 로 처음 값을 초기화 한 이후로는
name 을 수정할 수가 없게 됐거든.
마찬 가지로, 다음 경우에서도 빨간줄이 그이며 오류가 발생해.
——
const numbers : readonly number[] = [1, 2, 3, 4]
numbers.push(5)
——
=> 빨간 줄이 그이는 위치는 push() 부분.
numbers 라는 변수는 number[] 라는 타입, 즉 숫자로 이루어진 배열 타입인데,
여기에 readonly 를 더하니 numbers 변수는 향후 수정이 불가능하게 되었어.
이로서 numbers 변수는 타입스크립트의 보호 하에 불변성을 지니게 된거야.
바깥에서 수정할 수 없다는 점에서 private 속성과 좀 닮은 구석이 있네.
2.
_______________________________
< 튜플 타입 >
‘ Tuple ‘ 은 array 를 생성할 수 있게 하는데, 최소한의 길이를 가져야 하고, 특정 위치에 특정 타입이 있어야 해.
우선 다음 예시를 확인하자.
——
const somePlayer : [string, number, boolean] = []
////
const somePlayer: [string, number, boolean]
Type '[]' is not assignable to type '[string, number, boolean]'.
Source has 0 element(s) but target requires 3.
——
=> somePlayer 아래에 빨간줄이 그이며 오류가 발생할 것임을 타입스크립트가 고지해줘. 오류의 내용은 //// 아래와 같아.
즉, “somePlayer 라는 변수는 배열이며 배열 안에는 [string, number, boolean] 이 담겨야 한다” 라는 뜻.
해당 배열은 최소 3개의 요소를 가지며, 각각의 요소는 순서대로 string, number, boolean 이어야 한다.
——
const somePlayer : [string, number, boolean] = ["min", 30, true]
——
이렇게 작성해 주면 아무런 문제도 없겠지.
만약 sonePlayer 라는 변수에 접근하여 값을 바꾸려고 한다면?
——
const somePlayer : [string, number, boolean] = ["min", 30, true];
somePlayer[0] = "minsoo"; // 정상 작동
somePlayer[0] = 1; // 오류 발생
——
=> 두 번째 줄은 정상적으로 작동하지만, 세 번째 줄에서는 빨간줄이 그이며 오류 발생.
왜? String 이어야 하는데 1 이라는 number 를 넣으려 하니까.
만약 readonly 를 추가한다?
——
const somePlayer : readonly [string, number, boolean] = ["min", 30, true];
——
=> 그럼 아예 외부에서 변형이 불가하겠지.
3.
_______________________________
< any 타입 >
——
let aaa;
let a_array = []
——
=> 위와 같을 경우, 둘 다 해당 변수의 타입은 “any” 타입이 된다.
aaa의 경우 어떤 타입의 값이든 들어올 수 있다 생각하고,
a_array 의 경우 배열 안에 어떤 타입의 데이터든 다 들어올 수 있다 생각.
즉, any 타입이라는 건 내가 ‘타입스크립트에서 벗어나고 싶다’ 라고 생각할 때 사용하는 타입인 거지.
사실 이러면 타입스크립트를 사용하는 의미가 없긴 해.
typeScript 설정에 any 사용을 막기 위해 추가할 수 있는 몇 가지 규칙이 있어.
그럼에도 불구하고 any 타입은 타입스크립트에 존재하는 타입이며, 사용법을 배워야 해.
——
const a : any[] = [1, 2, 3, 4];
const b : any = true
a + b
——
=> any 를 사용한다는 건, 타입스크립트를 벗어나서 자바스크립트로 돌아온다는 것을 의미.
따라서 위와 같은 명청한 코드에서도 작동을 하며 에러를 띄우지 않아.
a + b = “1, 2, 3, 4false” 뭐 이런 식으로 값을 주겠지 뭐…
그럼에도 불구하고, 가끔은 any 를 사용해야 할 때가 있어.
물론 그럴 지라도 any 를 사용하는 건 좋지 못해.
'내일배움캠프_개발일지 > TypeScript 연습' 카테고리의 다른 글
TypeScript 연습 <1> -6- (0) | 2023.01.27 |
---|---|
TypeScript 연습 <1> -5- (0) | 2023.01.26 |
TypeScript 연습 <1> -4- (1) | 2023.01.25 |
TypeScript 연습 <1> -3- (0) | 2023.01.25 |
TypeScript 연습 <1> -1- (0) | 2023.01.19 |