*이 게시물은 이정환 강사님의 '한 입 크기로 잘라먹는 타입스크립트' 강의를 수강한 뒤 정리한 글입니다.
원시타입(Primitive Type)
- 동시에 한개의 값만 저장할 수 있는 타입.
- number, string, boolen, null, undefined, 리터럴 타입
※ 만약 null을 임시값으로 설정하고 싶다면? : strictNullChecks 옵션을 false로 설정(tsconfig.json)
let numA : null // js에선 가능
let numA: number = null; // ts 에러
※ 리터럴 타입 : 딱 하나의 값만 포함하는 타입.
let numA: 10 = 10; // 10외의 값 저장 x
let strA: "hello" = "hello"
let boolA: true = true;
let boolB: false = false;
배열
// 일반 배열정의
let numberArr: number[] = [1,2,3]
let strArr : string[] = ['hello','im','van']
// 제네릭 방식: 제네릭은 차후 정리
let boolArr : Array<boolean> = [true, false, true]
※ 다양한 타입의 배열요소를 가질 땐 어떻게 정의할까? : 유니온(Union) 타입 사용
let multiArr : (number | string)[] = [1, 'hello']
※ 다차원 배열 타입 정의
let doubleArr : number[][] = [
[1,2,3],
[4,5]
]
튜플
- 길이와 타입이 고정된 배열
- JS는 없고 TS에만 있는 특수한 타입
- 본질은 배열이기 때문에 배열의 메소드 역시 사용 가능(ex: push, pop)
let tup1 : [number, number] = [1,2]
let tup2 : [number, string, boolen] = [1, 'hi', true]
※ 튜플을 왜 사용하는 걸까?
길이와 값을 고정해놓으면 값이 잘못 들어갔을때 바로 오류를 찾을 수 있음
// 유저 정보 저장하는 튜플
// 0번 인덱스에는 회원의 이름, 1번 인덱스에는 아이디 순번 저장
const users : [string, number][] = [
["이정환", 1],
["김철수", 2],
["최하니", 3],
[4, "조땡땡"] // 오류발생
]
객체
- 객체의 타입은 'object' 가 아닌 '객체 리터럴 타입'을 사용해야 한다!
- 이유: object 타입은 단순히 값이 객체라는 것을 표현할 뿐, 해당 객체가 가지고 있는 프로퍼티 정보를 전혀 가지고 있지 않음. 따라서 객체.key 형태로 값에 접근하면 오류가 발생함.
- 따라서 객체의 프로퍼티를 직접 나열하는 객체 리터럴 방식을 사용.
// 객체 리터럴 타입
let user : {
id: number,
name : string
} = {
id: 1,
name: "이정환"
};
user.id // 1 출력
타입스크립트는 객체의 타입을 정의할 때 프로퍼티를 기준으로 객체의 구조를 정의하듯이 타입을 정의한다!
-> 구조적 타입 시스템
※ 특수한 프로퍼티 정의하기
1. 선택적 프로퍼티(Optional Property)
- 있어도 되고 없어도 되는 프로퍼티를 정의
- 프로퍼티 이름 뒤에 '?' 를 붙임
let user : {
id ?: number,
name: string
} = {
id: 1,
name: "이정환"
}
user = {
name: "홍길동" // 정상
}
2. 읽기 전용 프로퍼티(Readonly Property)
- 수정x, 읽기만 할 수 있는 프로퍼티 정의
let user : {
id: number,
readonly name : string
} = {
id : 1,
name: "이정환"
}
user.name = "최정환" // 오류! 수정 불가능
타입 별칭
- 변수를 선언하듯 타입을 별도로 정의할 수 있는 기능
- 'type 타입이름 = 타입' 형태
- 변수 선언 시 타입 주석과 함께 사용할 수 있음
- 동일 스코프에선 중복된 이름으로 여러개의 별칭을 선언할 수 없음(변수와 동일)
// 타입별칭 선언
type User = {
id: number,
name: string,
nickname: string,
birth: string
}
// 타입별칭 사용
let user1 : User = {
id: 1,
name: "이정환",
nickname: "winterlood",
birth: "1997.01.07"
}
let user2 : User = {
id: 2,
name: "홍길동",
nickname: "houhou"
birth: "2001.12.17"
}
인덱스 시그니처
- 객체 타입을 유연하게 정의할 수 있도록 돕는 특수문법
- 정의해야 할 타입이 많을 때 사용하면 유용
// ex: 국가 언어코드 저장하는 객체 정의
type ContryCodes = {
Korea: string,
UnitedState: string,
UnitedKingdom: string,
// ... 이렇게 100개씩 지정하려면 너무 오래걸리고 유지보수도 힘듦.
}
// 인덱스 시그니처 사용
type ContryCodes = {
[key: string] : string;
}
let contryCodes : CountryCodes = {
Korea: "ko",
UnitedState: "us",
UnitedKingdom: "uk"
// ... 등등 100개 국가 정의
}
- 만약 반드시 정의해야 하는 프로퍼티가 있다면? : 직접 명시하면 됨
- 이 때, 새로 추가한 프로퍼티의 value 값은 기존 인덱스 시그니처의 value 값과 타입이 호환/일치해야 함
type CountryCodes = {
[key: string] : string,
Korea: string
USA: number // 오류
}
- 다양한 타입의 값으로 인덱스 시그니처를 사용하고 싶다면? : 유니온(Union) 타입 사용
type countryCodes {
[key: string]: string | number; // 값이 'string' 또는 'number' 타입일 수 있음
}
let countryCodes : countryCodes = {
korea : "ko",
usa : 123
}
열거형 타입(Enum)
- JS는 없고 TS에만 존재하는 타입
- 여러개의 값을 나열하는 용도로 사용
- 숫자형 enum과 문자형 enum이 있음
- TS에만 존재하나, 컴파일 후 다른 TS 타입들처럼 사라지지 않고 JS 객체로 변환됨
enum Role { // 괄호 바로 쓰는 것 주의!
ADMIN,
USER,
GUEST
}
- enum에는 각 멤버에 숫자를 할당할 수 있고, 멤버들을 값으로 활용할 수도 있음
- 따로 숫자를 할당하지 않으면 자동으로 0부터 할당됨.
enum Role {
ADMIN = 0,
USER = 1,
GUEST = 2
}
const user1 = {
name: "이정환",
role : Role.ADMIN
}
const user2 = {
name: "홍길동",
role : Role.USER
}
const user3 = {
name: "이정환",
role : Role.GUEST
}
enum Role {
ADMIN = 10, // 10 할당
USER, // 11 할당(자동)
GUEST, // 12 할당(자동)
}
const user1 = {
name: "이정환",
role: Role.ADMIN, // 10
};
const user2 = {
name: "홍길동",
role: Role.USER, // 11
};
const user3 = {
name: "아무개",
role: Role.GUEST, // 12
};
- 문자형 enum: 모든 멤버의 값이 문자열 값인 열거형
- 문자형 enum은 객체 선언시 대소문자나 철자 실수로 인한 오류를 방지하는데 유용함
enum Language {
korean = "ko",
english = "en"
}
enum Role {
ADMIN,
USER,
GUEST,
}
// 숫자형, 문자형 enum 을 섞어 쓸 수 있음
const user1 = {
name: "이정환",
role: Role.ADMIN,
lang : Language.korean
}
any 타입
- TS에서만 존재. 타입 검사를 받지 않는 일종의 치트키 타입.
- 범용적으로 사용하기 좋으나, 타입검사를 받지 않아 오류 발생 위험이 높은 만큼 되도록 사용하지 않는 것이 좋음.
Unknown 타입
- any와 비슷하지만 좀 더 안전한 타입
- 어떤 타입의 값이든 할당받을 수 있지만, 반대로 다른 변수에 할당하는 것은 안 됨. => 값의 "저장" 만 가능!
- 사칙연산, 메서드 사용 X
let unknownVar = unknown;
unknownVar = "" // 정상
unknownVar = 1 // 정상
unknownVar = () => {} // 정상
let num: number = 10;
num = unknownVar; // 오류
unknownVar * 2 // 오류
- 만약 unknown 타입의 값을 받았는데 연산하고 싶다면?
-> 조건문으로 타입을 좁혀야 한다!
if(typeof unknownVar === "number"){
unknownVar * 2
}
void 타입
- 아무 값도 없음을 의미.
- 보통 return 값이 없는 함수의 반환값 타입을 정의할 때 사용
- 변수의 타입으로 활용할 경우, 오직 undefined 값만 담을 수 있음
- tsconfig.json에서 'strictNullCheck 옵션'을 false 처리한다면 void에 null도 담을 수 있게 됨!
// 반환값 없는 함수의 타입을 지정할 떄
function fun2(): void {
console.log('hello')
}
// 변수를 void 타입으로 선언할 때
let a: void;
a = undefined
never 타입
- 불가능을 의미하는 타입.
- 보통 무한루프처럼 함수가 어떤 값도 반환할 수 없는 상태에서 사용.
- 의도적인 오류를 발생시킬 경우에도 반환값을 never 타입으로 정의.
- any를 포함한 어떤 값도 해당 타입 변수에 값을 담을 수 없음.
// 무한루프
function func3(): never {
while(true) {}
}
// 의도적으로 오류를 발생시킬 때
function func4():never {
throw new Error()
}'개발공부' 카테고리의 다른 글
| #6. 클래스 (0) | 2025.02.27 |
|---|---|
| #5. 인터페이스 (0) | 2025.02.26 |
| #4. 함수와 타입 (0) | 2025.02.25 |
| #3. 타입스크립트 이해하기 (0) | 2025.02.20 |
| #1. 타입스크립트 개론 (0) | 2025.02.17 |
