[TS] Typescript 가보자고 1

민디·2024년 7월 3일

RN

목록 보기
4/4
post-thumbnail

안녕-하요! 민디입니다! 🤭
진짜 오랜만에 돌아왔습니다! 최근 근황을 조금 이야기해보자면 이번에 스터디를 시작했습니다!
React Native 를 이용해 클론 코딩을 하고, 해보지 못했던 기술들을 써보는 스터디를 만들어서 시작했는데, 정말 두근두근 하네요

그런 의미로 이번 스터디에서 제가 새롭게 도전해보는 것 중 하나인 TypeScript 에 대해 스터디하면서 차근 차근 블로깅을 해보려고 합니다.
스터디에서 함께하기 때문에 종종 이렇게 찾아올 것 같아요!
자 그럼 TypeScript 가보자고 1편을 빠르게 시작해보겠습니다!
(잠깐 심호흡 좀 후하후하)

아래 내용은 TypeScript Handbook 을 정리한 내용입니다.

기본 타입

💡 프로그램이 유용하려면 숫자, 문자열, 구조체, 불리언 값과 같은 간단한 데이터 단위가 필요합니다. TypeScript 는 JavaScript 와 거의 동일한 데이터 타입을 지원하며, 열거 타입을 사용하여 더 편리하게 사용할 수 있습니다.

Boolean

가장 기본적인 데이터 타입은 JavaScript, TypeScript 에서 boolean 값이라고 일컫는 참/거짓(true/false) 값입니다.

let isDone: boolean = false;

Number

TypeScript 의 모든 숫자는 부동 소수 값입니다. 부동 소수에는 number 라는 타입이 붙여지며, 16진수, 10진수 리터럴에 더불어 ECMAScript 2015에 소개된 2진수, 8진수 리터럴도 지원합니다.

let decimal: number = 6;
let hex: number = 0xf00d;
let binary: number = 0b1010;
let octal: number = 0o744;

String

TypeScript 에서는 텍스트 데이터 타입을 string 으로 표현합니다. 큰 따옴표(")작은 따옴표(') 로 문자열 데이터를 감싸 사용합니다.

let color: string = "blue";
color = 'red';

템플릿 문자열을 사용하면 여러 줄에 걸쳐 문자열을 작성할 수 있고, 표현식을 포함시킬 수도 있습니다.
백틱/백쿼트(`) 문자로 감싸고, ${ expr } 과 같은 형태로 표현식을 포함시킬 수 있습니다.

let fullName: string = 'Bob Bobbington';
let age: number = 37;
let sentence: string = 'Hello, my name is ${fullName}. Ill be ${age + 1} years old next month.';

위는 아래 sentence 선언과 동일합니다.

let sentence: string = "Hello, my name is " + fullName + ".\n\n" + 
	"I'll be " + (age + 1) + " years old next month.";

Array

값 들을 배열로 다룰 수 있습니다. 두 가지 방법으로 사용할 수 있으며, 첫 번째 방법은 타입 뒤에 [] 를 사용하는 것입니다.

let list: number[] = [1, 2, 3];

두 번째 방법은 제네릭 배열 타입을 사용하는 것입니다.

let list: Array<number> = [1, 2, 3];

🤔 그렇다면 여기서 두 개의 차이는 뭘까요?

여러가지의 차이가 있는데 가장 큰 차이는 다차원 배열이나 복잡한 배열을 표현할 때 차이가 있습니다.
단일 타입의 배열을 정의할 때는 [] 표기법이 더 간단하고 가독성이 좋지만,
제네릭 배열 타입은 다차원 배열이나 복잡한 타입의 배열을 정의 할 때 더 명확하고 읽기 쉬운 표현을 제공합니다.

두 개의 차이를 여러 가지로 자세히 봐보자면,

선언방식

T[] 는 요소 타입 T 뒤에 대괄호 [] 를 붙여 배열 타입을 정의합니다.
Array<T> 는 TypeScript 의 제네릭 타입을 사용하여 배열 타입을 정의합니다.

let numbers1: number[] = [1, 2, 3];
let strings1: string[] = ['a', 'b', 'c'];

let numbers2: Array<number> = [1, 2, 3];
let strings2: Array<string> = ['a', 'b', 'c'];

타입 표현

T[] 는 타입 스크립트의 배열 타입에 대해 간단하고 직관적인 표현입니다.
Array<T> 는 제네릭을 사용하는 좀 더 정형화된 표현힙니다.

let matrix1: number[][] = [[1, 2], [3, 4]];
let matrix2: Array<Array<number>> = [[1, 2], [3, 4]];

복잡한 타입과의 조합

제네릭 배열 타입 Array<T> 는 복잡한 타입과 조합할 때 더 명확할 수 있습니다.
객체 배열을 정의할 때 제네릭 표현이 더 읽기가 쉽습니다.

let objects1: { name: string, age: number }[] = [{name: 'Alice', age: 25}, {name: 'Bob', age: 30}];
let objects2: Array<{name: string, age: number}> = [{name: 'Alice', age: 25}, {name: 'Bob', age: 30}];

인터페이스와의 결합

인터페이스와 결합할 때도 제네릭 배열 타입이 유리할 수도 있습니다.

interface Person {
	name: string;
	age: number;
}

let people: Person[] = [{ name: 'Alice', age: 25 }, { name: 'Bob', age: 30 }];

let people2: Array<Person> = [{ name: 'Alice', age: 25 }, { name: 'Bob', age: 30 }];

유니온 타입과의 사용

let mixedArray1: (number | string)[] = [1, 'a', 2, 'b'];

let mixedArray2: Array<number | string> = [1, 'a', 2, 'b'];

함수 파라미터와 반환 타입

function getArray1(items: number[]): number[] {
	return items;
}

function getArray2(items: Array<number>): Array<number> {
	return items;
}

이 처럼 모든 상황에 둘 다 사용할 수 있으며, 각자의 선택에 따라 사용하면 됩니다!

Tuple

요소의 타입과 개수가 고정된 배열을 표현할 수 있습니다. 단, 요소들의 타입이 모두 같을 필요는 없습니다.

let x: [string, number];
x = ["hello", 10]; // 성공
x = [10, "hello"]; // 실패

정해진 인덱스에 위치한 요소에 접근하면 해당 타입이 나타납니다.

console.log(x[0].substring(1)); // 성공
console.log(x[1].substring(1)); // 오류, number 에는 substring 이 없음

정해진 인덱스 외에 다른 인덱스에 있는 요소에 접근하면, 오류가 발생하여 실패합니다.

x[3] = "world"; // 오류, [string, number] 타입에는 프로퍼티 3 이 없다.

console.log(x[5].toString()); // [string, number] 타입에는 프로퍼티 5가 없다.

Enum

표준 자료형 집합과 사용하면 도움이 될 만한 데이터 형입니다. 값의 집합에서 더 나은 이름을 붙여줄 수 있습니다.

enum Color { Red, Green, Blue }
let c: Color = Color.Green;

기본적으로 enum 은 0 부터 시작하여 번호를 매깁니다.
멤버 중 하나의 값을 수동으로 설정하여 번호를 바꿀 수도 있습니다.

enum Color { Red = 1, Green, Blue }
let c: Color = Color.Green;

또는 모든 값을 수동으로 설정할 수도 있습니다.

enum Color { Red = 1, Green = 2, Blue = 4 }
let c: Color = Color.Green;

enum 의 유용한 기능 중 하나는 매겨진 값을 사용해 enum 멤버의 이름을 알아낼 수 있다는 것입니다. 위의 예제에서 2 라는 값이 위의 어떤 Color enum 멤버와 매칭되는지 알 수 없을 때, 이에 일치하는 이름을 알아낼 수 있습니다.

enum Color { Red = 1, Green, Blue }
let colorName: string = Color[2];

console.log(colorName); // 값이 2 인 'Green' 이 출력된다.

Any

가끔 알지 못하는 타입을 표현해야 할 때도 있습니다.
이 값들은 사용자로부터 받은 데이터나 서드 파티 라이브러리 같은 동적인 컨텐츠에서 올 수도 있습니다. 타입 검사를 하지 않고, 그 값들이 컴파일 시에 그냥 통과하길 원할 때 사용합니다.

let notSure: any = 4;
notSure = "maybe a string instead";
notSure = false;

기존에 JavaScript 로 작업할 수 있는 강력한 방법으로, 컴파일 중에 점진적으로 타입 검사를 하거나, 하지 않을 수도 있습니다.

let notSure: any = 4;
notSure.ifItExists(); // 성공, ifItExists 는 런타임엔 존재한다.
notSure.toFixed(); // 성공, toFixed 는 존재한다. (컴파일러는 검사하지 않는다.)

또한 any 타입은 타입의 일부만 알고 전체는 알지 못할 때 유용합니다.

let list: any[] = [1, true, "free"];

list[1] = 100;

🤔 ifItExists 와 toFixed 가 뭘까요?

ifItExists

일반적으로 조건부 접근 연산자 (옵셔널 체이닝) 과 관련이 있습니다.
옵셔널 체이닝은 객체의 속성이나 메서드가 존재하는지 여부를 확인하고, 존재하지 않는 경우 undefined 를 반환하는 안전한 접근 방법입니다.

Optional Chaining (옵셔널 체이닝)

연산자 ?. 를 사용하여 객체의 속성이나 메서드에 안전하게 접근할 수 있습니다.
해당 속성이나 메서드가 존재하지 않으면 undefined 를 반환합니다.

interface Person {
	name: string;
	address?: {
		street?: string
	};
}

let person: Person = {
	name: "John",
	address: {
		street: "123 Main St"
	}
};

let street = person.address?.street; // 123 Main St
let city = person.address?.city; // undefined

toFixed

Number 객체 메서드로, 숫자를 고정 소수점 표기법으로 변환한 문자열을 반환합니다.
소수점 이하 자릿수를 지정할 수 있습니다.
숫자를 문자열로 변환하며, 선택적으로 소수점 이하 몇 자리수까지 표시할 지 지정할 수 있습니다.

let num = 123.4567;

console.log(num.toFixed(2)); // 123.46
console.log(num.toFixed(0)); // 123
console.log(num.toFixed(5)); // 123.45670

Void

어떤 타입도 존재할 수 없음으로 나타내기 때문에, any 타입의 반대 타입입니다.
보통 함수에서 반환값이 없을 때 반환 타입을 표현하기 위해 사용됩니다.

function warnUser(): void {
	console.log("This is my warning message");
}

void 타입 변수를 선언하는 것은 유용하지 않습니다. 왜냐하면 그 변수에는 null(-stricNullChecks 를 사용하지 않을 때만 해당) 또는 undefined 만 할당할 수 있기 때문입니다.

let unusable: void = undefined;
unusable = null; // 성공 '--stricNullChecks' 를 사용하지 않을 때만

Null and Undefined

undefinednull 둘 다 각각의 타입입니다. void 처럼 그 자체로 유용한 경우는 거의 없습니다.

let u: undefined = undefined;
let n: null = null;

기본적으로 nullundefined 는 다른 모든 타입의 하위 타입입니다.
nullundefinednumber 와 같은 타입에 할당할 수 있다는 것을 의미합니다.
—stricNullChecks 를 사용하면 nullundefined 는 오직 any 와 각자 자신들 타입에만 할당이 가능하며, 일반적인 에러를 방지하는 데 도움을 줍니다.
string 또는 null 또는 undefined 를 허용하고 싶은 경우 유니언 타입인 string | null | undefined 를 사용할 수 있습니다.

🤔 void, null, undefined 에 대해 더 알아봅시다.

void

함수의 반환 타입에 사용되며, 함수가 값을 반환하지 않을 때 사용됩니다.

function logMessage(message: string): void {
	console.log(message);
}

let result: void = logMessage("hello, Typescript!");

null

어떤 값도 없음을 명시적으로 나타내는 타입입니다.
TypeScript 의 strictNullChecks 옵션이 활성화 된 경우, null 은 별도의 타입으로 취급되며, 이를 할당할 수 있는 변수는 명시적으로 null 타입을 포함해야 합니다.

let value: null = null;

let maybeNumber: number | null = null;
maybeNumber = 10;
maybeNumber = null;

undefined

초기화 되지 않은 변수의 기본 값이자, 명시적으로 값이 정의되지 않음을 나타내는 타입입니다.
null 과 비슷하게 strictNullChecks 옵션이 활성화 된 경우 별도의 타입으로 취급됩니다. 함수의 반환값으로도 사용될 수 있습니다.

let value: undefined = undefined;

function doNothing(): undefined {
	return undefined;
}

strictNullChecks 활성화 방법

TypeScript 설정 파일 (tsconfig.json) 을 수정합니다.
compilerOptionsstrictNullChecks 옵션을 추가해서 true 로 설정해주면 됩니다.

 "compilerOptions": {
    "strict": true,               // 추가: 모든 엄격한 타입 검사 옵션을 활성화
    "strictNullChecks": true,     // 추가: null 및 undefined에 대한 엄격한 검사
  },

여기까지 1차로 TS 를 정리해보았습니다!
휴~ 이제 점점 더 더워지고, 비도 많이오고 난리네요.. 다들 건강 조심하시구 비 조심하세요!
그럼 다음에 또 보아요!
모두들 안녕-쟈네-👋

profile
이(this || 異) 세계에서 개발자를 하고 있습니다.

0개의 댓글