1. 타입을 알아야 하는 이유
변수는 데이터를 저장하는 공간이고, 여러가지 타입이 있을 수 있다. 타입을 이애하고 사용하면 코드의 가독성과 안정성이 향상된다. 잘못된 타입을 사용하면 런타임에러가 발생하는데, 코드가 복잡해질수록 찾기 어려워진다. 타입 안정성은 코드가 예상한 타입대로 동작함을 보장하는 것이다.
1) 기본타입
- boolean : 참(true) 혹은 거짓(false) 값을 나타낸다. 조건문, 비교연산 등에서 주로 사용한다.
- number : typescript에서 사용하는 모든 숫자를 나타낸다. 정수는 short, int, long을 쓰고, 실수는 float, double를 쓴다. 또한 ts만의 특징으로 2,8,16진수도 표현할 수 있다.
- string : 텍스트 테이터를 나타내는데, 작은따옴표('), 큰 따옴표("), 백틱(`)으로 나타낸다. 텍스트를 조작하거나 출력할 때 사용한다.
- 튜플(tuple) : 서로 다른 타입의 원소를 순서에 맞게 가질 수 있는 특수한 형태의 배열. 어떤 타입의 원소를 허용할 지 정의하면 됨.
- enum : 열거형 데이터 타입. 값이 설정되어 있지 않으면 기본적으로 숫자 0으로 시작. number 혹은 string 값만 할당 가능
2) const, leadonly
const 키워드로 선언하면 변수가 아닌 상수가 된다. 값을 변경할수 없으니 연산자로 다시 할당이 불가능하다. leadonly는 Typescript에서 등장한 키워드인데, 객체의 속성을 불변으로 만드는 키워드이다. 즉 클래스의 속성이나 인터페이스의 톡성을 변경할 수 없게 만든다.
class Person { // 클래스는 다른 강의에서 자세히 설명해드릴게요!
readonly name: string;
readonly age: number;
constructor(name: string, age: number) {
this.name = name;
this.age = age;
}
}
const person = new Person('Spartan', 30);
console.log(person.name); // 출력: 'Spartan'
console.log(person.age); // 출력: 30
person.name = 'Jane'; // 에러: 'name'은 readonly 속성이므로 다시 할당할 수 없어요!
person.age = 25; // 에러: 'age'은 readonly 속성이므로 다시 할당할 수 없어요!
leadonly를 const로 치환해서 쓰면 클래스의 속성에 const 키워드를 사용할 수 없다고 에러를 출력한다. const 키워드는 일반변수를 상수화할 때 사용하는 것이니까.
3) any, unknown, union
가변적인 타입의 데이터를 저장하고 싶다면 any를 쓰기보다는 unknown이 권장되고, 일일이 정의할 수 있다면 union 사용이 그나마 가장 낫다.
- any : 모든 타입의 슈퍼 타입. 타입 안정성과 유지 보수성을 저해할 수 있으니 가급적 사용하지 않는 것을 권장.
- unknown : any보단 안전. 모든 타입을 저장할 수 있는 것은 같지만, 그 값을 다른 타입의 변수에 할당하려면 타입단언(Type Assertion)을 통해 명시적으로 타입을 확인해야함.
- union : unknown도 결국 재할당이 일어나지 않으면 타입 안정성이 보장되지 않기에, union은 여러 타입 중 하나를 가질 수 있는 변수를 선언할 때 사용한다. 아래는 사용사례이다.
type StringOrNumber = string | number; // 원한다면 | boolean 이런식으로 타입 추가가 가능해요!
function processValue(value: StringOrNumber) {
if (typeof value === 'string') {
// value는 여기서 string 타입으로 간주됩니다.
console.log('String value:', value);
} else if (typeof value === 'number') {
// value는 여기서 number 타입으로 간주되구요!
console.log('Number value:', value);
}
}
processValue('Hello');
processValue(42);
2. 고급타입
1) enum과 object literal
a) enum 복습
enum은 열거형 데이터 타입이라서 상수의 그룹화를 위해선 enum이 아주 좋은 타입이 될 수 있다. 코드의 가독성을 높이고 명확한 상수 값을 정의할 수 있다. 하지만 특정한 숫자 값으로 매핑되어야 하면 직접 할당해줘야 한다.
b) object literal(객체 리터럴)
객체 리터럴은 키 + 값의 쌍으로 구성된 객체를 정의하는 방식이다. enum과 흡사하지만 enum이라는 키워드 대신 변수를 선언하듯이 let, const를 사용한다. enum의 각 멤버는 상수였기 때문에, number, string 타입의 값만 대입할 수 있지만, 객체 리터럴은 어떤 타입의 값도 대입할 수 있다. 즉, 객체리터럴은 다양한 테이터 타입을 지원하여 유연한 구조를 가지고 코드 내에서 사용하기 전에 할당되어야 하므로 런타임 에러를 방지할 수 있다.
2) 유틸리티 타입
- Partial<T> : 타입 T의 모든 속성을 선택적으로 만들어 기존 타입의 일부 속성만 제공하는 객체를 쉽게 생성할 수 있다.
interface Person {
name: string;
age: number;
}
const updatePerson = (person: Person, fields: Partial<Person>): Person => {
return { ...person, ...fields };
};
const person: Person = { name: "Spartan", age: 30 };
const changedPerson = updatePerson(person, { age: 31 });
- Required<T> : Partial과는 반대로 타입 T의 모든 속성을 필수적으로 만든다. T타입 객체에 정의된 모든 속성이 반드시 전부 제공되는 객체를 생성할 때 쓰인다.
interface Person {
name: string;
age: number;
address?: string; // 속성 명 뒤에 붙는 ?가 뭘까요
}
- Readonly<T> : 타입T의 모든 속성을 읽기 전용으로 만든다. 이를 통해 readonly 타입의 속성들로 구성된 객체가 아니어도 완전한 불변 객체로 취급할 수 있다.
interface DatabaseConfig {
host: string;
readonly port: number; // 인터페이스에서도 readonly 타입 사용 가능해요!
}
const mutableConfig: DatabaseConfig = {
host: "localhost",
port: 3306,
};
const immutableConfig: Readonly<DatabaseConfig> = {
host: "localhost",
port: 3306,
};
mutableConfig.host = "somewhere";
immutableConfig.host = "somewhere"; // 오류!
- Pick<T, K>는 타입 T에서 K 속성들만 선택하여 새로운 타입을 만드는 것이다. 이를 통해 타입의 일부 속성만을 포함하는 객체를 쉽게 생성할 수 있다.
interface Person {
name: string;
age: number;
address: string;
}
type SubsetPerson = Pick<Person, "name" | "age">;
const person: SubsetPerson = { name: "Spartan", age: 30 };
- Omit<T, K>는 타입 T에서 K 속성들만 제외한 새로운 타입을 만든다. Pick과 반대라고 생각하면 된다.
interface Person {
name: string;
age: number;
address: string;
}
type SubsetPerson = Omit<Person, "address">;
const person: SubsetPerson = { name: "Alice", age: 30 };
'Sparta > TIL' 카테고리의 다른 글
24.03.11 TIL - nest.js 패키지 (0) | 2024.03.12 |
---|---|
24.03.08 TIL - Nest.js 파일 구조 (0) | 2024.03.09 |
24.03.06 TIL - Typescript(2) (0) | 2024.03.07 |
24.03.05 TIL - Typescript (0) | 2024.03.06 |
24.03.04 TIL - Nest.js 기초 (5) | 2024.03.05 |