TypeScript
[TypeScript] 타입
wwxs
2024. 8. 19. 15:18
타입(Type)
- 타입 명시(작성)가 필수 사항 X → 프로그램의 안정성과 가독성을 높이는 역할
타입 명시 방법
- 타입 어노테이션 (type annotation - 타입 주석)
- 변수명 뒤에 콜론을 사용하여 JS 코드에 타입을 정의
타입스크립트 타입의 종류
1. 기본 타입(원시 타입 - string, number, boolean 등)
- 변수명 뒤에 콜론 사용
- typeof 연산자 사용 시 나타내는 변환값과 동일한 이름으로 명시 (소문자)
더보기
더보기
let name: string = '홍동현';
// 권장) 변수명: 타입명 = 값;
let age: number = 50;
let isStudent:boolean = false;
2. 배열(list, array) 타입
- 순서가 있는 요소의 모을을 나타내는 자료 구조
- 변수명 뒤에 콜론 사용 → 기본타입명 뒤에 배열을 나타내는 [ ]를 첨부
- 제네릭 타입 → Array<기본타입>
더보기
더보기
// 변수명 뒤에 콜론 사용
let list1: string[] = ['1', '2', '3'];
// - 제네릭 타입
let list2: Array<number> = [4, 5, 6]
3. void 타입
- void : 아무런 값이 없다 → 주로 함수에서 반환값이 없거나 return 키워드가 있더라도 반환하는 값이 없을 때 사용되는 타입
더보기
더보기
function voidType(parameter: number): void {
// 함수의 타입 정의
// >> 파라미터(매개변수)와 반환값(return값) 정의 가능
// >> TS에서 "파라미터"에 타입을 명시하지 않으면 오류 발생
// : 함수 내에서 사용할 변수에 대한 안정성을 요구
// : 변수의 타입 명시와 동일
// >> 반환값의 타입 명시는 파라미터를 정의하는 ()소괄호 뒤에
// 콜론을 붙여 정의
console.log(parameter);
return;
}
voidType(10); // 10
4. null & undefined 타입
- null 타입 : 아무것도 없음, 데이터가 잘못된 경우
- undefined 타입 : 변수 생성은 했지만 안에 값이 없을 경우
5. any 타입 (모든)
- 모든 타입에 대해 허용하는 타입
- 타입 검사 오류가 발생하는 것을 방지 (모든 타입과 호환 가능)
- TS를 JS처럼 사용
6. never 타입
- 절대 발생하지 않는 값의 타입
- 함수가 예외를 발생시키거나 끝나지 않을 때 사용
더보기
더보기
function error(message: string): never{
throw new Error(message);
}
// error('에러 발생!'); - Error
타입스크립트의 객체 타입
객체 타입 지정(명시)
- { } 중괄호를 사용하여 표현
- 각 데이터별 타입 명시의 구분은 세미콜론(;) 사용을 권장
더보기
더보기
const user: {
// 각 타입 구분 시 콤마와 세미콜론 모두 사용 가능
// >> 세미콜론 사용을 권장
name: string;
height: number;
favorite: any[];
// 타입에서 명시한 속성은 반드시 객체 내부에 존재
} = {
// 객체 내부에서 각 속성의 구분은 콤마(,)로 표시
name: '홍동현',
height: 169,
// hobby: 'exercise' - Error
// >> 객체는 타입 명시를 하지 않은 속성은 정의할 수 X
favorite: [1, '운동', false, null, undefined, ['안녕', 1]]
}
객체의 선택 속성
- 선택적 프로퍼티
- 속성명 "뒤"에 물음표(?)를 붙여 해당 속성이 존재하지 않을 수도 있음을 표현
더보기
더보기
const ldk: {
name: string;
height?: number; // 타입 명시 속성 뒤에 물을표를 작성 (선택적 프로퍼티)
} = {
name: '이도경',
// height: 157 - 생략해도 오류X
}
읽기 전용 속성
- 속성명 "앞"에 readonly 키워드를 사용하여 해당 속성의 재할당을 금지
- 해당 키워드가 붙은 속성은 const 키워드를 사용하여 정의한 변수와 유사
더보기
더보기
const readonlyName: {
readonly name: string;
readonly age?: number;
address?: string;
} = {
name: '홍동현',
age: 50,
}
// readonlyName.age = 30; - Error
타입 별칭
- 새로운 타입 이름을 생성해서 기존의 타입을 참조할 수 있게 하는 기능
- 코드의 재사용성과 가독성 향상
- type 타입별칭 = 타입;
1. 변수 타입 별칭
더보기
더보기
type TextType = string;
// >> 타입 별칭은 다른 코드와의 식별을 위해 대문자로 시작
let textMsg: TextType = '텍스트 문자열입니다.'
type NumberType = number;
let num: NumberType = 1923;
2. 객체 타입 별칭
- 타입 별칭 내에서도 선택적 프로퍼티 & 읽기 전용 속성 사용 가능
더보기
더보기
type UserType = {
name?: string;
readonly height: number;
};
const user1: UserType = {
name: "홍동현",
height: 169,
};
// user1.height = 170; // Error
const user2: UserType = {
// name: '이도경',
height: 157,
};
3. 함수 타입 별칭
- User 타입인 매개변수를 받아 boolean 타입의 반환값을 생성하는 함수
더보기
더보기
type User = {
id: string;
password: string;
};
type ValidUser = (user: User) => boolean;
const isValidUser: ValidUser = (user) => user.id !== "";
let userA: User = {
id: "qwerty",
password: "qwe123",
};
let userB: User = {
id: "",
password: "qweqwe123123",
};
console.log(isValidUser(userA)); // true
console.log(isValidUser(userB)); // false
Union(유니언) 타입
- 여러 타입 중 하나가 될 수 있는 값을 나타내는 방법
- 값에 허용된 타입을 두 개 이상으로 지정
- OR 연산자 (| ; vertical bar) 기호를 사용하여 표현
유니언 타입의 사용
- 변수, 함수의 매개변수, 반환값 등에서 모두 사용 가능
- 타입의 유연성을 제공
- 무분별한 any 사용을 방지
- type UnionType = Type1 | Type2 | ...;
더보기
더보기
type VariableType = string | number | boolean | string[];
let value: VariableType = '문자';
value = 123;
value = true;
value = ['안녕', '반가워'];
타입 별칭에서 union 타입 사용시
- 정확한 타입 지정을 위해 타입 가드를 사용
- 타입 가드 : 조건문을 통해 타입을 좁혀나가는 방식
더보기
더보기
type Union = number | string;
function getAge(age: Union){
if(typeof age === 'number'){
age = age.toFixed();
return age;
} else{
age = age.toUpperCase();
return age;
}
}
console.log(getAge(12.345)); // 12
console.log(getAge('12 years old')); // 12 YEARS OLD
Intersection(인터섹션) 타입
- 여러 타입을 하나로 결합하여 모든 타입의 기능을 갖춘 단일 타입을 생성
- 여러 타입을 모두 만족하는 하나의 타입
- And 연산자 (&) 를 사용하여 구현
- type 타입별칭 = Type1 & Type2 & ...;
더보기
더보기
type Admin = {
isAdmin: boolean;
}
type User = {
id: string;
password: string;
}
// 관리 사용자
type AdminUser = Admin & User;
function createAdminUser(user: User): AdminUser {
// 스프레드 연산자를 사용하는 새로운 객체 생성
return { ...user, isAdmin: true };
}
let newAdminUser: User = {
id: 'qwe123',
password: 'qweqwe123123'
}
let adminUser1 = createAdminUser(newAdminUser);
console.log(adminUser1);
// { id: 'qwe123', password: 'qweqwe123123', isAdmin: true }
리터럴 타입(Literal, 문자 그대로의)
- 특정 '값' 만을 가질 수 있는 타입을 정의할 때 사용
리터럴 타입의 종류
1) const 키워드를 사용하여 직접 리터럴 값을 할당(초기화)
더보기
더보기
let str1 = '안녕하세요'; // string 타입
str1 = 'hello';
str1 = '곤니치와';
const str2 = '반갑습니다.'; // "반갑습니다." 타입
// str2 = 'hi'; - Error
// str2 = '니하오'; - Error
2) 변수에 타입 명시를 리터럴 값으로 명시
더보기
더보기
let num1: 123 = 123; // 123 타입
// num1 = 234; - Error
// num1 = 345; - Error
let boo1: true = true; // true 타입
// bool1 = false; - Error
리터럴 타입의 활용
- 주로 type 키워드(타입 별칭)와 함께 사용
- 유니언 타입과 함께 사용하여 다양한 값을 표현함과 동시에 제한 가능
- 변수 혹은 매개변수가 특정 값들 중 하나만을 가질 수 있도록 제한
더보기
더보기
//? 리터럴 타입 예시
// 1) Directions(방향) 타입을 정의
type Directions = 'up' | 'down' | 'left' | 'right';
let moveUp: Directions;
moveUp = 'up';
// moveUp = '위';
// 2) 함수의 인자로 리터럴 타입을 지정하여 특정 값으로 제한
function setAlignment(align: 'left' | 'center' | 'right') {
// 함수 내용
// let container = document.querySelector('#container');
// container.style.textAlign = align;
}
setAlignment('center');
// setAlignment('중앙'); - Error
// 3) IoT 국비반 학생 관리 시스템
type Students = '이승아' | '이도경' | '정재원' | '최준혁' | '최소윤';
let students: Students;
// students = '김준일';
// +) 리터럴 타입의 경우 여러 타입의 혼합이 가능
type mixedType = 'yes' | 'no' | 1 | 2 | 3;
let gameState: mixedType;
gameState = 'yes';
gameState = 3;
gameState = 1;
// gameState = 123;
// gameState = '노우';
gameState = 'no';
객체 리터럴 타입
- 실제 객체 데이터 정의
더보기
더보기
type UserType = {
name: '홍동현';
height: 169;
}
let user: UserType = {
name: '홍동현',
// height: 170 // '170' 형식은 '169' 형식에 할당할 수 없습니다.
height: 169
};
객체의 구조적 타이핑(덕 타이핑)
- 객체의 타입을 실제 값보다는 그 구조나 멤버에 의해 결정하는 방식
- 객체의 형태가 같다면, 같은 타입으로 간주
더보기
더보기
type Person = {
name: string;
age: number;
}
function greet(person: Person) {
console.log(`Name: ${person.name}, age: ${person.age}`);
}
// Person 타입이 명시적으로 구현되지 않은 객체 생성
const p1 = {
name: '홍동현',
age: 50
}
const p2 = {
name: '이도경',
age: 60,
hobby: '배구보기'
}
const p3 = {
name: '정수은'
}
greet(p1); // Person과 구조가 일치하기 때문에 Person 취급
greet(p2); // 구조적 타이핑에 의해 Person 취급 (hobby속성을 무시)
// greet(p3); // >> Person 타입 속성 구조와 일치하지 않음
중첩된 객체 타입 정의
더보기
더보기
type Address = {
street: string;
readonly city: string;
zipCode?: string; // 선택적 프로퍼티 (옵셔널)
}
type UserProfile = {
username: string;
email: string;
address: Address;
}
let userA: UserProfile = {
username: '장지민',
email: 'qwe123',
address: {
street: '123 St',
city: 'Busan'
}
}
// userA.address.city = '대전';
userA.address.street = '중앙대로';
객체의 인덱스 서명
- 객체의 모든 속성에 대해 타입을 정의하지 않고 키와 값의 타입만 정의하여 구조를 유연하게 적용하는 방법
더보기
더보기
type UserDataType = {
name: string; // - 일반적인 객체 속성 타입 명시
//? 인덱스 서명 사용 방법
// [propertyName: indexType]: valueType;
// 키의 타입과 값의 타입을 미리 명시
[key: string]: string | number | boolean; // 키는 string 사용을 권장
// >> valueType에는 어떤 타입이든 가능
}
let user1: UserDataType = {
name: '이승아',
height: '123',
age: 50,
isTeacher: true
}
// user1.email = [123, 234];
user1.email = 'qwe123';
타입스크립트의 함수
더보기
더보기
function greet(name: string): string {
return `Hello ${name}`;
}
//? 함수에 타입 별칭을 사용하는 경우
// >> 화살표 함수의 체계를 사용
type ArrowFuncType = (name: string) => string;
const arrowFunc: ArrowFuncType = (name) => {
return `Hi ${name}`
}
console.log(arrowFunc('선하영'));
console.log(arrowFunc('지수민'));
선택적 매개변수와 기본 매개변수
1) 선택적 매개변수
- 함수 호출시 생략 가능
- 변수명 뒤에 ? 작성
2) 기본 매개변수
- 기본값을 할당
- 함수 호출 시 생략하는 경우에 기본값을 자동 할당
- 매개변수명 = '기본값'
더보기
더보기
function select(name?: string, greeting: string = '안녕') {
if (name) {
console.log(`${greeting}, ${name}`);
} else {
console.log(`${greeting}, guest`);
}
}
select(); // 안녕, guest
select('이승아'); // 안녕, 이승아
select('반가워'); // 안녕, 반가워
select(undefined, '반가워') // 반가워, guest
select('이도경', '반가워'); // 반가워, 이도경
선택적 매개변수와 기본 매개변수 사용 시
- 선택적 매개변수는 반드시 필수 매개변수(인자로 전달) 뒤에 작성
- 기본 매개변수는 필수와 선택적 매개변수 양쪽에 작성 가능 (어디든)
- 기본 매개변수가 앞서는 경우 생략하려면 반드시 undefined를 전달
Rest(나머지) 매개변수
- 함수에 전달하는 여러 개의 매개변수를 그룹화하여 배열로 전달하는 기능
- ...연산자(spread 연산자)를 사용하여 매개변수명 앞에 사용
더보기
더보기
function sum(a: number, b: number, ...c: number[]) {
return c.reduce((c1, c2) => c1 + c2, 0); // c1 += c2
}
console.log(sum(1, 2, 3, 4, 5)); // 12
console.log(sum(1, 2)); // 0
console.log(sum(1, 2, 10, 20, 30)); // 60
Rest 매개변수의 주의점
- 항상 매개변수 리스트의 마지막에 위치
- 타입 명시를 배열로 작성