해당 프로젝트에 npm init 해서 node.js 설치
npm install --save-dev lite-server
의존성 설정(package.json) 들어가서 "start" 명령어에 lite-server 등록하기
tsc 파일명
// tsc app.ts
그럼 ts 파일이 컴파일되어 js 파일이 생성된다.
만약 IDE 단에서 오류를 발견했다고 하더라도 컴파일 자체를 막진 않는다. 따라서 컴파일 하기 전에 에러가 있는지 잘 확인하고 고친 후에 컴파일을 해야 한다. 안그러면 오류가 있는 버전의 JS 파일이 도출된다.
TS는 JS의 슈퍼셋. 즉 JS의 기존 데이터타입을 다 가지고 있다. 이에 더해서 TS 만이 제공하는 데이터타입들이 있다.
런타임이 아닌 개발 단계에서 타입이 결정된다.(dynamic types vs static types)
TS에는 타입 추론기능이 내장되어 있으므로 어느정도는 알아서 인식한다.
그러나 명시적으로 타입을 지정해주는 습관을 가져야 더 안전하고 DX 측면에서도 좋다.
1. 기본 데이터 타입 (Primitive Types)
let num: number = 10;
let str: string = "Hello, TypeScript";
let bool: boolean = true;
let n: null = null;
let u: undefined = undefined;
let sym: symbol = Symbol("sym");
let big: bigint = 9007199254740991n;
2. 객체 타입 (Object Types)
// Object
let obj: {
name: string,
age: number
} = {
name: "John",
age: 25
};
// Array
let numbers: number[] = [1, 2, 3, 4];
let strings: Array<string> = ["one", "two", "three"];
// Tuple
let tuple: [string, number];
tuple = ["hello", 10];
// Enum
enum Color {
Red,
Green,
Blue
}
let c: Color = Color.Green;
// Function
let add: (x: number, y: number) => number;
add = function (x: number, y: number): number {
return x + y;
};
// Interface
interface User {
name: string;
age: number;
}
let user: User = { name: "Alice", age: 30 };
// Class
class Person {
constructor(public name: string, public age: number) {}
}
let person: Person = new Person("Bob", 40);
3. 제네릭 (Generics)
function identity<T>(arg: T): T {
return arg;
}
let output1 = identity<string>("myString");
let output2 = identity<number>(100);
class GenericNumber<T> {
zeroValue: T;
add: (x: T, y: T) => T;
}
let myGenericNumber = new GenericNumber<number>();
myGenericNumber.zeroValue = 0;
myGenericNumber.add = (x, y) => x + y;
4. 고급 타입 (Advanced Types)
// Union
let union: number | string;
union = 10;
union = "hello";
// Intersection
type Person = { name: string };
type Employee = Person & { company: string };
let employee: Employee = { name: "John", company: "TechCorp" };
// Type Aliases
type ID = number | string;
let userId: ID;
userId = 123;
userId = "ABC123";
// Literal Types
let specificString: "hello" = "hello";
let specificNumber: 10 = 10;
// Mapped Types
type Readonly<T> = {
readonly [P in keyof T]: T[P];
};
type Partial<T> = {
[P in keyof T]?: T[P];
};
interface Point {
x: number;
y: number;
}
let readonlyPoint: Readonly<Point> = { x: 10, y: 20 };
// Conditional Types
type NonNullable<T> = T extends null | undefined ? never : T;
type Result = NonNullable<string | number | undefined>; // string | number
// Type Guards
function isString(x: any): x is string {
return typeof x === "string";
}
function example(x: string | number) {
if (isString(x)) {
console.log(x.toUpperCase());
} else {
console.log(x.toFixed(2));
}
}
1. 매개변수 타입 지정하기
const sum = (number1: number, number2: number) => {
return number1 + number2;
}
console.log(sum(4, 5));
2. input 태그로 두 숫자를 받아서 결과 보여주기 (HTML 코드는 생략)
// as ~~ 는 타입 지정
const number1Input = document.getElementById("number1") as HTMLInputElement;
const number2Input = document.getElementById("number2") as HTMLInputElement;
const submitButton = document.getElementById("submit") as HTMLButtonElement;
const resultDiv = document.getElementById("result") as HTMLDivElement;
submitButton.addEventListener("click", () => {
const number1 = parseFloat(number1Input.value);
const number2 = parseFloat(number2Input.value);
if (isNaN(number1) || isNaN(number2)) {
resultDiv.textContent = "숫자를 입력해 주세요.";
} else {
const sum = number1 + number2;
console.log(sum);
resultDiv.textContent = sum.toString();
}
})
둘 다 타입들의 묶음이 필요할 때 사용하는데, 언제 enum을 쓰고 언제 alias를 사용할까?
보통, enum은 일반적으로 연관성이 있다고 받아들여지는 대상들에 대해서 사용한다. (ex: 접근권한(admin, user ..), Status(로딩, 성공, 에러) 등)
그 외적으로 프로젝트마다 생기는 특수한 필요성에 의해 타입 묶음이 필요한 경우에는 Alias를 사용한다.
쉽게 말하면, 복잡한 타입 선언이 필요한데, 자주 쓰일 것 같아서 별칭을 지어주고 싶을 때 Alias를 자주 사용한다.
enum 사용 예시 1 (요일)
enum Weekday {
Monday,
Tuesday,
Wednesday,
Thursday,
Friday,
Saturday,
Sunday
}
function getWeekdayName(day: Weekday): string {
switch (day) {
case Weekday.Monday:
return "Monday";
case Weekday.Tuesday:
return "Tuesday";
case Weekday.Wednesday:
return "Wednesday";
case Weekday.Thursday:
return "Thursday";
case Weekday.Friday:
return "Friday";
case Weekday.Saturday:
return "Saturday";
case Weekday.Sunday:
return "Sunday";
}
}
console.log(getWeekdayName(Weekday.Monday)); // "Monday"
enum 사용 예시2 (상태를 관리하는 객체)
enum Status {
Loading,
Success,
Error
}
interface ApiResponse {
status: Status;
data?: any;
error?: string;
}
function handleApiResponse(response: ApiResponse) {
switch (response.status) {
case Status.Loading:
console.log("Loading...");
break;
case Status.Success:
console.log("Data:", response.data);
break;
case Status.Error:
console.log("Error:", response.error);
break;
}
}
alias 사용예시 (타입 별칭)
type User = {
id: number;
name: string;
role: "admin" | "user" | "guest";
};
function printUserInfo(user: User) {
console.log(`ID: ${user.id}, Name: ${user.name}, Role: ${user.role}`);
}
const user: User = {
id: 1,
name: "John Doe",
role: "admin"
};
printUserInfo(user); // "ID: 1, Name: John Doe, Role: admin"
TypeScript | Return 타입 명시, Function 타입 명시, 콜백함수 타입 명시 (0) | 2024.06.09 |
---|