티스토리 뷰
TypeScript
[ 타입스크립트(TypeScript)란 ]
TypScript 는 정적 타입 검사자 (TypeScript: A Static Type Checker) 이다. 프로그램을 실행시키지 않으면서 코드의 오류를 검출하는 것을 정적검사 라고 한다. 자바스크립트 코드가 실행(런타임) 중 오류를 발견하는 것과 달리 타입스크립트는 코드 작성(컴파일) 중 오류를 발견해 준다. 아래 예시를 참고하자 ‼️
// 자바스크립트
// : 오류안남
let age = 25; // 숫자
age = "스물다섯"; // 문자
// 타입스크립트
// : 컴파일 오류발생
let age : number = 25; // 숫자
age = "스물다섯"; // 컴파일 오류 발생(문자열 할당 불가능)
[ 타입스크립트(TypeScript)는 어떻게 실행될까? ]
타입스크립트를 컴파일하면 자바스크립트 코드가 만들어진다. 타입오류가 발생하고 있는 타입스크립트 코드는 컴파일 시 타입 검사를 통과할 수 없기 때문에 자바스크립트 코드로 변환되지 않아 실행할 수 없게 된다. 타입스크립트는 컴파일 결과 타입 검사를 거쳐 자바스크립트 코드로 변환되는데 이때 만약 코드에 오류가 있다면 컴파일 도중 실패하게 되므로 자바스크립트를 보다 더 안전하게 사용하기 위하여 미리 한번 코드를 검사하는 용도로 사용된다고 볼 수 있다.
✔︎ TypeScript 컴파일 과정 (.ts 코드에서 .js 코드로의 변환 )
① Parsing(구문 분석)
❶ TypeScript 코드를 읽고 AST(Abstract Syntax Tree; 코드를 트리 형태로 표현한 자료구조) 로 변환.
② Type Checking (타입 검사)
❶ AST를 기반으로 타입을 검사
❷ 타입 오류가 있으면 컴파일 실패.
③ Transformation (변환)
❶ AST에서 TypeScript의 타입 정보 제거
❷ TypeScript 고유 문법( interface, type, enum 등) 제거
④ Code Generation( JavaScript 코드 생성)
❶ AST를 기반으로 최종 JavaScript 코드 생성
[ 타입스크립트(TypeScript) 문법 ]
① 정적 타입(Static Typing)
: TypeScript는 변수를 선언할 때 타입을 지정할 수 있다.
let age: number = 25;
age = "twenty-five"; // ❌ 오류: 'string' 형식을 'number'에 할당할 수 없음
② 타입 추론(Type Inference)
: TypeScript는 명시적으로 타입을 선언하지 않아도 타입을 추론한다.
let name = "Alice"; // TypeScript는 'name'을 자동으로 'string'으로 추론
name = 10; // ❌ 오류: 'number' 형식을 'string'에 할당할 수 없음
③ 인터페이스(Interface)
: 인터페이스를 사용하여 객체의 구조를 정의할 수 있다.
interface User {
name: string;
age: number;
isAdmin?: boolean; // 선택적 속성
}
const user: User = {
name: "John",
age: 30
};
console.log(user.name); // ✅ 정상 동작
console.log(user.isAdmin); // ✅ 선택적 속성이므로 undefined 가능
④ 제네릭(Generics)
: 제네릭을 사용하면 유연하고 재사용 가능한 코드 작성이 가능하다.
function identity<T>(arg: T): T {
return arg;
}
console.log(identity<string>("Hello")); // ✅ "Hello"
console.log(identity<number>(123)); // ✅ 123
⑤ 유니온 타입(Union Type)
: 하나의 변수에 여러 개의 타입을 허용할 수 있다.
function printId(id: number | string) {
console.log(`Your ID is: ${id}`);
}
printId(101); // ✅ 정상 동작
printId("abc123"); // ✅ 정상 동작
printId(true); // ❌ 오류: 'boolean'은 허용되지 않음
⑥ 타입 가드(Type Guards)
: 타입을 런타임에서 안전하게 구별할 수 있다.
function printLength(value: string | number) {
if (typeof value === "string") {
console.log(value.length); // ✅ 문자열일 때만 length 속성 사용 가능
} else {
console.log("숫자는 length 속성이 없음");
}
}
printLength("Hello"); // ✅ 출력: 5
printLength(123); // ✅ 출력: "숫자는 length 속성이 없음"
⑦ 열거형(Enum)
: 열거형을 사용하면 명확한 값의 집합을 만들 수 있다.
(열거형을 사용하면 특정 상태값을 의미 있는 이름으로 관리할 수 있다.)
enum Status {
Pending,
InProgress,
Done
}
let currentStatus: Status = Status.InProgress;
console.log(currentStatus); // ✅ 출력: 1
⑧ 클래스와 상속
: TypeScript는 객체지향 프로그래밍을 지원하며, 클래스와 상속을 사용할 수 있다.
class Animal {
name: string;
constructor(name: string) {
this.name = name;
}
makeSound(): void {
console.log("Some sound...");
}
}
class Dog extends Animal {
breed: string;
constructor(name: string, breed: string) {
super(name);
this.breed = breed;
}
makeSound(): void {
console.log("Woof! Woof!");
}
}
const dog = new Dog("Buddy", "Golden Retriever");
dog.makeSound(); // ✅ "Woof! Woof!"
⑨ 타입 별칭
: 인터페이스와 비슷하지만, 유니온 타입을 포함한 다양한 타입을 정의할 수 있다.(객체, 유니온 타입, 튜플 등)
// UserRole처럼 특정 값만 가질 수 있도록 제약 가능
type UserRole = "admin" | "user" | "guest";
type User = {
id: number,
username: string,
role: UserRole,
};
const user2: User = {
id: 1,
username: "Bob",
role: "admin"
};
강의 실습 코드
강의에서 사용되는 예시 실습 코드 1, 2 를 작성해 두었다.
위의 링크를 통해 강의를 확인할 수 있다.
[ TypeScript example 1 ]
// intro to pizza app
type Pizza = {
id: number,
name: string,
price: number
}
type Order = {
id: number,
pizza: Pizza,
status: "ordered" | "completed"
}
let cashInRegister = 100 // 계산대에 있는 현금
let nextOrderId = 1
let nextPizzaId = 1
const menu : Pizza[] = [
{id: nextPizzaId++, name: "Margherita", price: 8},
{id: nextPizzaId++, name: "Pepperoni", price: 10},
{id: nextPizzaId++, name: "Hawaiian", price: 10},
{id: nextPizzaId++, name: "Veggie", price: 9}
]
let orderQueue : Order[] = []
function addNewPizza(pizzaObj : Omit<Pizza, "id">) : Pizza {
const pizza : Pizza = {
id: nextPizzaId++,
...pizzaObj
}
menu.push(pizza)
return pizza
}
addNewPizza({name: "Chicken Bacon Ranch", price: 12})
addNewPizza({name: "BBQ Chicken", price: 12})
addNewPizza({name: "Spicy Sausage", price: 11})
console.log(menu)
function placeOrder(pizzaName: string) : Order | undefined{
let selectedPizza = menu.find(pizzaObj => pizzaObj.name == pizzaName)
if(!selectedPizza){
console.error(`${pizzaName} does not exist in the menu`)
return
}
cashInRegister += selectedPizza.price
const newOrder : Order = {id: nextOrderId++, pizza: selectedPizza, status : "ordered" }
orderQueue.push(newOrder)
return newOrder
}
function addToArray<Type> (array: Type[], item: Type): Type[] | undefined{
array.push(item)
return array
}
// example usage:
addToArray<Pizza>(menu, {id: nextPizzaId++, name: "Chicken Bacon Ranch", price: 12})
addToArray<Order>(orderQueue, {id: nextOrderId++, pizza: menu[2], status: "completed"})
console.log(menu)
console.log(orderQueue)
function CompleteOrder(orderId : number) : Order | undefined {
const order = orderQueue.find(order => order.id == orderId)
if(!order){
console.error(`${orderId} was not found in orderQueue`)
return
}
order.status = "completed"
return order
}
export function getPizzaDetail(identifier: string|number) : Pizza | undefined {
if(typeof(identifier) === "string"){
return menu.find(pizza => pizza.name.toLowerCase() === identifier.toLowerCase())
}else if(typeof(identifier) === "number"){
return menu.find(pizza => pizza.id === identifier)
}else{
throw new TypeError("parameter `identifier` must be either a string or a number")
}
}
// placeOrder("Chicken Bacon Ranch")
// CompleteOrder(1)
// console.log("Menu", menu)
// console.log("Cash in register", cashInRegister)
// console.log("Order queue", orderQueue)
// what we learnt
// 01 basic, literal, and custom types
// 02 optional properties
// 03 unions
// 04 type narrowing
// 05 utility types
// 06 generic
[ TypeScript example 2]
type UserRole = "contributor" | "member"| "admin"
type User = {
id: number,
username: string,
role: UserRole
}
// type updatedUser = { // ? : means optional
// id?: number,
// username?: string,
// role?: "contributor" | "member"| "admin"
// }
type updatedUser = Partial<User> // same meaning with the above codes
let userRole : UserRole = "member"
// 위에 선언한 type을 지켜줘야 함.
// let userRole2: User = {
// username: "exampleUser",
// role: "guest"
// };
let nextUser = 1
const users: User[] = [
{id: nextUser++, username: "john_doe", role: "member"},
{id: nextUser++, username: "jane_doe", role: "admin"},
{id: nextUser++, username: "guest_user", role: "contributor"},
{id: nextUser++, username: "charlie_brown", role: "member"},
]
function updateUser(id: number, updates: updatedUser){
const foundUser = users.find(user => user.id === id)
if(!foundUser){
console.error("USER NOT FOUND")
return
}
// user object.assign to update the found user in place
Object.assign(foundUser, updates)
}
// omit: 특정 속성만 제거한 타입을 정의
function addNewUser(newUser: Omit<User, "id" | "user">) : User {
const user: User = {
id: nextUser++,
...newUser //spreaad
}
users.push(user)
return user
}
// example usage:
addNewUser({username: "joe_schmoe", role:"member"})
// example updates:
// updateUser(1, {username: "new_john_doe"});
// updateUser(4, {role: "contributor"});
console.log(users)
// example updates
function fetchUserDetails(username: string): User{
const user = users.find(user => user.username === username)
if(!user){
throw new Error(`user with username ${username} not found`);
}
return user
}
// let value : any = 1 // " type : any " means turning off typescript checking
// value = "hi"
// value.map()
// when should i use any?
// in short: dont
// 개념정리
// utility types
// 01. like a function, they take other types in as a parameter and return a new type. with some changes made to it
// 02. built-in to typescript; perform commonly-needed modifications to existing types
// 03. use "generics" syntax using angle branckets (<>)
// what does the partial type do ?
// this modifies the type you pass in and turns all properties into optional properties
// what does the omit type do ?
// omit takes in a type AND a string(or union of strings)
// property name(s), and returns a new type with those
// properties removed
// Generics
// 01 add flecibility to existing functions, types, etc
// 02 act like function parameters, but for types
// 03 use angle blancket syntax(<>)
const gameScores = [14, 21, 33, 42 ,59]
const favoriteThings = ["raindrops on roses", "whiskers on kittens", "bright copper kettles", "warm woolean mittens"]
const voters = [{name: "Alice", age: 42}, {name:"Bob", age:77}]
function getLastItem<Type>(array: Type[]) : Type | undefined {
return array[array.length-1]
}
console.log(getLastItem(gameScores))
console.log(getLastItem(favoriteThings))
console.log(getLastItem(voters))
let a = 258
a = "hi"
Reference
https://ts.winterlood.com/d67c7b28-c191-46ee-9bdc-2ae8643c2028
- Total
- Today
- Yesterday
- 자료구조
- 코드업 기초
- 운영체제
- 스터디
- 완전탐색
- 프로그래머스강의
- CS
- CS 스터디
- 데이터베이스
- 리스트
- 자료구조와알고리즘 23강
- Greedy sort
- It
- 리스트함축
- 자바
- 리스트2
- 파이썬
- SW
- 리스트 복사
- 이진탐색
- 연결리스트활용
- 정렬
- 보험
- https
- CS.
- 네트워크
- 프로그래머스
- 알고리즘
- 이차 리스트
- 프로세스 주소공간
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | ||||||
2 | 3 | 4 | 5 | 6 | 7 | 8 |
9 | 10 | 11 | 12 | 13 | 14 | 15 |
16 | 17 | 18 | 19 | 20 | 21 | 22 |
23 | 24 | 25 | 26 | 27 | 28 | 29 |
30 | 31 |