1. 타입스크립트 환경으로 프로젝트 생성하기
react-native CLI 에서 0.71 이상 버전부터는 기본적으로 타입스크립트 환경으로 프로젝트를 생성한다.
npx react-natie-init LearnTypeScript
2. 타입 이해하기
타입스크립트에서 변수를 선언할 때 해당 변수의 타입을 지정할 수 있다.
타입을 지정할 때에는 변수 이름 뒤애 : 타입 형태로 지정할 수 있다.
2-1. number 타입
- 숫자를 의미하는 모든 값을 포함하는 타입
- 단순 정수 뿐만 아니라 소수, 음수, Infinity, NaN 등의 특수한 숫자들도 포함임!
// number
let num1: number = 123;
let num2: number = -123;
let num3: number = 0.123;
let num4: number = -0.123;
let num5: number = Infinity;
let num6: number = -Infinity;
let num7: number = NaN;
2-2. String 타입
- 단순 쌍타옴표 문자열 뿐만 아니라 작은 따옴표, 백틱, 템플릿 리터럴로 만든 모든 문자열 포함
// string
let str1: string = "hello";
let str2: string = 'hello';
let str3: string = `hello`;
let str4: string = `hello ${str1}`;
2-3. boolean 타입
// boolean
let bool1 : boolean = true;
let bool2 : boolean = false;
2-4. 유니언 타입
- 하나의 변수나 함수 매개변수가 여러 타입 중 하나를 가질 수 있도록 함.
- |(파이프) 기호를 사용하여 두 개 이상의 타입을 결합하여 만든다.
- 유니언 타입은 특정 값이나 변수가 여러 종류의 타입을 가질 수 있을 때 매우 유용
- 다양한 입력을 처리할 수 있는 코드를 작성할 수 있당
let value: string | number;
value = "Hello"; // OK
value = 42; // OK
// value = true;
// 오류: 'boolean' 타입은 'string | number' 타입에 할당할 수 없습니다.
위의 코드에서 value 는 string 혹은 number 타입을 가져야 하므로
두 타입에 해당하지 않는 boolean 을 넣으면 오류남
2-5. any 타입
- any 타입은 기본적으로 모든 타입을 허용하는 역할을 한다.
- 종종 TypeScript의 타입 시스템에서 벗어나고 싶을 때 사용한다. (= 타입 안전성 회피 옵션 )
- any 타입을 사용하면 해당 변수에 어떤 값이든 할당할 수 있으며, 해당 변수로 어떤 작업을 해도 컴파일 오류가 발생하지 않는다.
- 외부 라이브러리에서 데이터를 가져오거나, JSON 파싱 등의 상황에서 정확한 타입을 알 수 없을 때 any를 임시로 사용할 수 있다.
- 하지만 타입안전성을 잃기 쉬우므로 꼭 필요할 때에만 사용하도록 하자~
let randomValue: any = 10;
randomValue = "Hello";
randomValue = true;
-> 문자열, 숫자, boolean 타입 다 들어간 것을 확인할 수 있음
function getValue(key: string): any {
// 서버에서 데이터를 가져온다고 가정
return someApiCall(key);
}
-> 외부 데이터가 어떠한 타입인지 정확히 모를 때.. 이런 식으로 사용할 수 있담
2-6. 배열타입
- 동일한 타입의 여러 값을 하나의 변수에 저장할 수 있는 타입.
- 배열 타입을 정의할 때, 배열에 들어갈 요소의 타입을 지정해 준다.
- 배열에 들어가는 모든 요소는 동일한 타입이여야 한다.
- 변수의 이름 뒤에 타입 주석의 시작을 의미하는 콜론(:) 작성한 후 [ ]
- 배열에 타입을 정의하면 typescript 엔진은 그 배열에 잘못된 타입의 요소를 추가하려고 할 때 오류 발생시킴
let numbers: number[] = [1, 2, 3, 4, 5]; // number 타입인 아이들만 담을 수있음
let strings: string[] = ["hello", "world"]; // string 인 아이들만 담을 수 있음
배열 타입을 지정해주는 것은 두가지 방식이 있다.
// 타입뒤에 '[]' 를 붙이는 방식
let names: string[] = ["Alice", "Bob", "Charlie"];
// 제너릭방식
let names: Array<string> = ["Alice", "Bob", "Charlie"];
위에서 배열 타입은 모두 같은 타입이어야 한다고 하였다.
하지만 만약!!! 여러 타입을 가지는 아이들을 배열로 묶고싶다면 어떻게 해야할까 ??
let multiArr: (number | string)[] = [1, "hello"];
-> 이렇게 유니언 타입을 활용하여 배열 안에 number 과 string 타입을 가진다는 것을 명시해주면 된다.
2-7. 튜플타입
- 배열 타입은 자바스크립트와 비슷하지만 튜플타입은 타입스크립트의 특수한 타입이다.
- 고정된 개수의 요소를 가지며 각 요소의 타입이 미리 지정되어 있어야 한다.
- 즉 길이와 타입이 고정된 배열이라고 볼 수 있다.
- 튜플을 사용하면 배열 내의 각 위치에 특정 타입의 값을 저장할 수 있다.
let person: [string, number] = ["hihilong", 25];
function getUser(): [number, string] {
return [1, "hihilong"];
}
배열 타입은 일반적으로 동일한 타입의 여러 값을 다룰 때 사용하고, 튜플 타입은 서로 다른 타입의 값을 고정된 구조로 다룰 때 사용한다.
3. 객체타입, 함수타입
3-1. 객체(object) 타입
- 객체가 가져야 할 속성과 해당 속성들의 타입을 정의하는 것이다.
- 객체 타입은 객체의 형태를 정의하기 때문에, 객체의 프로퍼티와 그 타입을 명확하게 지정할 수 있다.
그런데 이런 코드를 생각해보자.
let obj: Princess = {
name: "hihilong",
age: 25
};
Princess.name;
// 오류: 'Princess' 타입에 'name' 속성이 없습니다.
Priness 의 타입에 Name 속성이 있는데도 없다는 오류가 뜬다.
왜그럴까? ?
object 타입은 내부 속성에 접근할 수 없어서
속성에 타입을 직접 명시해주지 않는다.
흠...이게 무슨 말이냐고 하면 그냥 값이 객체임을 표현하는 것 뿐이지 타입을 명시해주지 않는다는 이야기이다.
object 타입으로 정의된 변수에 접근할 때는 그 내부 속성에 직접 접근할 수 없기 때문에, 속성을 사용할 때 타입 검사를 할 수 없다는 얘기
따라서 이 타입은 객체의 프로퍼티에 대한 정보를 전혀 가지고 있지 않기 때문에 이러한 프로퍼티에 접근하려고 하면 오류가 발생할 수 있다는 것이다.
그렇다면 객체의 구조를 그대로 타입으로 만들고 싶다면 어떻게 해야할까? ?
바로바로 ~ ~
객체 리터럴 타입을 사용해준다.
📌 객체 리터럴 타입이란 ? ?
- 중괄호를 열고 객체의 각 속성과 그 속성의 타입을 명확하게 정의하는 타입이다.
- 객체가 어떤 속성을 가지고 있는지, 각 속성의 타입이 무엇인지를 알 수 있다.
let Princess: {
name: string;
age: number
} = {
name: "hihilong",
age: 25
};
Princess.name; // 'name'은 'string' 타입
Princess.age; // 'age'는 'number' 타입
따라서!
object 타입을 사용하는 것보다는 객체 리터럴 타입을 사용하는 것이 훨씬 더 안전하고, 타입스크립트의 타입 검사 기능을 충분히 활용할 수 있게 된다! !
3-2. 함수타입
- 함수 타입은 함수의 매개변수와 반환 값의 타입을 정의하는 것.
- 함수 타입을 정의하면, 함수가 어떤 인자를 받아서 어떤 타입의 값을 반환해야 하는지를 명확하게 알 수 있다.
- 보통 콜백 함수, 함수형 프로그래밍, API 함수 정의할 때 자주 쓰임
type GreetFunction = (name: string) => string;
const greet: GreetFunction = (name) => {
return `Hello, ${name}!`;
};
자 그렇다면... 이렇게 타입을 지정해준것은 알겠다.
근데 나는 가끔은 이런 함수나 배열에... 꼭 값을 안넣고 싶을 때가 있을 것이다.
그럴 때는 어떻게 할 수 있을까?
선택적 프로퍼티를 사용해보자 !
4. 기타 타입
4-1. 선택적 프로퍼티 (optional Property)
- 선택적 프로퍼티는 객체의 일부 속성을 필수로 지정하지 않고, 필요에 따라 포함할 수 있도록 정의하는 방법.
- 즉, 객체 타입에서 특정 속성이 선택적으로 존재할 수 있도록 한다.
- 속성 이름 뒤에 ? 를 붙여서 정의한다.
- 이는 해당 속성이 없어도 객체가 유효함을 정의하는 것이다.
(1) 배열에서의 선택적 프로퍼티의 사용
type Person = {
name: string;
age?: number; // age는 선택적 프로퍼티
isStudent: boolean;
};
const person1: Person = {
name: "hihilong",
isStudent: true, // age 속성이 없어도 오류 없음
};
const person2: Person = {
name: "byebyelong",
age: 30, // age 속성이 있는것도 굿~
isStudent: false,
};
(2) 함수에서의 선택적 프로퍼티의 사용
type GreetFunction = (name: string, greeting?: string) => string;
const greet: GreetFunction = (name, greeting = "Hello") => {
return `${greeting}, ${name}!`;
};
console.log(greet("hihilong"));
여기서 greeting 에 선택적 프로퍼티를 주어 매개변수를 꼭 전달하지 않아도 되게 하였다. -
따라서 이 코드를 실행하면 "Hello, Alice!"가 출력된다.
왜냐하면 greeting 매개변수를 전달하지 않았기 때문에 기본값 "Hello"가 사용되었기 때문
console.log(greet("hihilong", "Good morning"));
여기서 는 "Good morning, hihilong!"이 출력된다.
여기서는 greeting 매개변수로 "Good morning"을 전달했기 때문에, 이 값이 사용됨
type Person = {
name: string;
age?: number;
isStudent: boolean;
};
function printAge(person: Person) {
if (person.age !== undefined) {
console.log(`Age is ${person.age}`);
} else {
console.log("Age is not provided");
}
}
const person1: Person = { name: "hihilong", isStudent: true };
printAge(person1);
// 출력: Age is not provided
const person2: Person = { name: "byebyelong", age: 30, isStudent: false };
printAge(person2);
// 출력: Age is 30
4-2. 읽기전용 프로퍼티
- 객체의 속성을 수정할 수 없도록 하는 기능.
- 이를 사용하면 객체를 생성한 후에 특정 속성의 값을 변경할 수 없도록 보장한다.
- 즉, 읽기 전용 프로퍼티는 한 번 설정된 값을 이후에 변경할 수 없게 한다.
- 속성이름 앞에 readonly 키워드를 붙인다.
type Person = {
readonly name: string; //name 은 이제 못바꿈
age: number;
};
const person: Person = {
name: "hihilong",
age: 25,
};
console.log(person.name); // "hihilong"
person.age = 26; // OK: 'age'는 읽기 전용아니라서 바꿔도 됨
person.name = "byebyelong";
// 오류: 'name'은 읽기 전용 속성이므로 변경할 수 없습니다.
5. 타입 자동추론
- 타입스크립트를 사용한다고 해서 모든 변수에 꼭 타입을 명시해줘야 하는 것은 아니다.
- 기본 타입들은 타입을 꼭 명시해주지 않아도 자동으로 추론하곤한다.
- 따라서 변수가 하나의 타입만 지니고 있다면 타입 선언을 생략해주어도 된다.
- 하지만.. 여러 타입을 지닐 수 있는 가능성이 있다면 타입을 명시해줘야한다.
let message = "Hello, World!";
message = "Hi there!"; // OK
// message = 42;
// 오류: 'number' 타입은 'string' 타입에 할당할 수 없습니다.
위 코드에서 message 변수는 명시적으로 타입이 되지 않지만 message에 "Hello, World!"라는 문자열이 할당된 것을 보고 자동으로 string 타입으로 추론할 수 있다. 따라서 이후 message 변수를 string으로 사용한다.
reference
책 <리액트 네이티브를 다루는 기술 - 김민준>
'TypeScript' 카테고리의 다른 글
[RN] 타입스크립트 개념 정리 (6) - 제네릭(Generic) 이란? (1) | 2024.08.24 |
---|---|
[RN] 타입스크립트 개념 정리 (5) - 클래스 의 this 와 new (0) | 2024.08.24 |
[RN] 타입스크립트 개념 정리 (4) - 클래스(Class) 란? (0) | 2024.08.24 |
[RN] 타입스크립트 개념 정리 (3) - 인터페이스란? (0) | 2024.08.24 |
[RN] 타입스크립트 개념 정리 (1) - 타입스크립트 사용 이유 (0) | 2024.08.24 |