📌 Type annotation
const val: number = 123
Type annotation: 변수 뒤에 ': number'로 타입을 지정해주는 것
형식은 다음과 같다.
value: type
🐵 원시 타입
Primitive (원시값)
: 불변, 객체가 아닌 값들
- String
- Number
- BigInt
- Boolean
- Symbol
- null
- undefined
const str: stirng = 'STRING'
const num: number = 123
const bool: boolean = true
const big: bigint = 100n
자바스크립트에서 이런 간단한 타입들은 타입 추론을 할 수 있기 때문에 굳이 타입을 지정하지 않아도 된다.
오히려, 타입 추론을 유도하는 것이 더 좋다.
원시값은 다음과 같이 활용하는 것이 좋다.
const str: 'string' = 'string'
const num:123 = 123
const nool: true = true
기본값을 지정해주면, 기본값 이외의 값이 할당되었을 때 오류를 발생시킨다.
💼 객체 타입
🤔 객체 타입을 지정할 때는 object로 지정하면 될까?
const obj: object = {
str: 'str',
num: 123,
child: {
str: 'str',
num: 123,
}
}
정답은 ❌이다.
obj.str.trim()
string 타입에만 적용이 되는 trim() 메서드를 호출하면 str에서 찾을 수 없다는 오류 메시지를 발생한다.
num도 마찬가지로 obj 안에서 찾지 못한다.
: object로 타입을 지정하는 것은 any와 다른 게 없는 상황이다.
🤔 그렇다면 어떻게 타입을 좁힐 수 있을까?
const obj: { str: string, num: number } = {
str: 'str',
num: 123,
}
위와 같이 객체 안 요소들에 대한 타입들을 자세하게 묘사해주어야 한다.
객체 안 객체는 다음과 같다.
const obj: { str: string,
num: number,
child: {
str: string,
num: number,
}
} = {
str: 'str',
num: 123,
child: {
str: 'str',
num: 123,
}
}
🚀 함수 타입
Function Type
함수 타입은 두 가지의 타입을 명시해주어야 한다.
- 매개변수
- 반환
function func(num: number, str: string): string{
return num + str
}
Function이라는 타입을 지정하는 것은 지양❌ 해주는 것이 좋다.
function func2(num1: Function, num2: Function): Function{
console.log(num1 + num2)
}
🤔 함수 표현식에서는 타입을 어떻게 지정해야 좋을까?
const func3 = (num: number, str: string): string => {
}
위와 같이 매개변수, 반환 타입을 지정해주면 된다.
반환 타입은 타입 추론이 잘 되는 편이기 때문에 필히 넣을 필요는 없다.
적어도 매개변수에는 타입을 넣자!
🎈 배열 타입
const arr = ['str', 123, false]
위외 같은 배열 타입(여러 타입이 있는 경우)은 튜플(Tuple)로 타입 지정을 해주어야 한다.
하나의 타입으로 이루어진 배열을 살펴보자.
const strArr: string[] = ['str', 'str2', 'str3']
const strArr: Array<string> = ['str', 'str2', 'str3']
위와 같이 배열 변수 우측에 타입을 지정해주면 된다.
두 가지 방법에 차이는 없다.
🙌 리터럴 타입
Literal Type
하나의 특정한 값을 가질 수 있는 타입
let letString = 'Hello'
const constString = 'Hello'
🤔 두 변수의 차이점은 무엇일까?
바로 타입 정의에서 letString은 string 타입이고, constString 은 "Hello"로 정의되어 있다.
🤔 왜 이런 차이점이 나타날까?
letString은 재할당할 수 있기 때문에 리터럴 타입으로 지정되어 있다.
반면에 constString은 재할당이 불가능하기 때문에 특정 값으로 지정되어 있다.
🍒 튜플 타입
Tuple Type
- 길이 고정 & 인덱스 타입이 고정
- 여러 다른 타입으로 이루어진 배열을 안전하게 관리
- 배열 타입의 길이 조절
const tuple: [number, string] = [1, 'A']
배열의 길이를 가변적으로 제어하는 예시를 아래에서 살펴보자.
const tuple: [number, ...string[]] = [0, 'A', 'B']
spread 연산자를 통해 배열의 길이도 2개 이상으로 제어할 수 있다.
🧛♂️ undefined null
- JavaScript에서와 마찬가지로 고유의 특별한 타입으로 인정한다.
- 이외에 void, never와 같이 더 세밀한 타입도 제공
- strictNullchecks가 핵심
예시를 아래에서 살펴보자.
function sayHello(word: string){
if(word === 'world'){
return 'hello' + word
}
return null
}
위의 함수는 에러가 발생하지 않고 함수의 반환 타입이 자동적으로 string | null로 설정되어 있다.
만약 반환 타입을 void로 설정하게 되면 에러가 발생한다.
만약 return; 으로 설정하게 되면 함수의 반환 타입이 자동적으로 string | undefined로 설정 된다.
정리
- return null ➡ null
- return ➡ undefined
- 반환하지 않음 ➡ void
팀에서 빈 값을 다루게 될 때, undefined를 사용할 지, null을 사용할 지 정하는 것이 좋다. (둘 중 하나만)
🧙♂️ any
any type
- 모든 값(타입)의 집합
- 사용하지 말자 ❌❌
- noImplicitAny or strict 옵션 true 권장
아래의 예시를 살펴보자.
function func(anyParam: any){
anyParam.trim()
}
위의 함수에서 trim() 메서드는 문자열에서만 사용이 가능하다.
이때 any 타입을 가진 anyParam이 문자열이 아닐 경우, 런타임에서 오류가 발생한다.
any 타입은 매우 위험하지 사용을 지양해야 한다.
any 타입을 사용하면 타입 추론이 안 되기 때문에 vs code에서 .을 찍어도 자동 완성이 되지 않지만,
타입을 지정하면 .을 찍었을 때 자동 완성 기능을 사용할 수 있다.
🌚 unknown
- 새로운 최상위 타입
- any 처럼 모든 값을 허용하지만 상대적으로 엄격하다.
- TS에서 unknown으로 추론하는 경우는 없으니 개발자가 직접 명시해야 함
- assertion 혹은 타입 가드와 함께 사용한다.
아래에서 any와 unknown 차이를 살펴보자.
function func(x: any){
let val1: any = x;
let val2: unknown = x;
let val3: string = x;
let val4: boolean = x;
let val5: number = x;
let val6: string[] = x;
let val7: {} = x;
}
any에는 모든 타입들이 포함되어 있기 때문에 에러가 발생하지 않는다.
🤔 함수의 매개변수를 any 대신 unknown으로 변경하면 어떻게 될까?
function func(x: unknown){
let val1: any = x;
let val2: unknown = x;
let val3: string = x;
let val4: boolean = x;
let val5: number = x;
let val6: string[] = x;
let val7: {} = x;
}
any와 unknown은 에러가 발생하지 않지만, 나머지 타입들에서 에러가 발생하게 된다.
또다른 예시를 살펴보자.
let num: any = 99;
num.trim();
any로 타입이 지정된 num 변수는 trim() 메서드를 호출해도 컴파일러에서는 에러가 발생하지 않고, 런타임에서 에러가 발생한다.
🤔 이를 unknown으로 변경해주면 어떻게 될까?
let num: unknown = 99;
num.trim();
컴파일러에서 에러를 발생시킨다.
num은 문자열이 아니기 때문에 trim() 메서드를 호출할 수 없다.
이럴 때 사용할 수 있는 것이 타입 가드이다.
: 타입을 검증하는 도구
let num: unknown = 99;
if(typeof num === 'string'){
num.trim();
}
위와 같이 타입 가드를 사용하여 엄격하고 안전하게 제어를 할 수 있다.
assertion : 타입을 강제하는 도구
let num: unknown = 99;
(num as string).trim();
위와 같이 타입을 강제하여 사용할 수 있다.
하지만 assertion보다는 타입 가드를 사용하는 것이 좋다.
💫 void
- 함수의 반환이 없는 경우를 명시
- 타입 추론에 위임하자
- JavaScript에서는 암시적으로 undefined 반환
- 그러나 void와 undefined는 TypeScript에서 같은 것이 아님
function voidFunc(){
//
}
위의 함수는 타입 추론에 의해 void 함수로 정의가 된다.
결론 : void 타입을 명시할 필요 없이 타입 추론에 위임하자!
'TypeScript' 카테고리의 다른 글
[TypeScript] TypeScript 시작하기 (0) | 2022.09.06 |
---|
Comment