Skip to content

Brem0827/TypeScript-23-2

Repository files navigation

Since author All Contributors

Watch on GitHub Star on GitHub Fork on GitHub

💎TypeScript

📔 201930324 이현종


이현종

💎 주차

  1. 💭1주차➡️
  2. 💭2주차➡️
  3. 💭3주차➡️
  4. 💭4주차➡️
  5. 💭5주차➡️
  6. 💭6주차➡️
  7. 🔖중간고사➡️
  8. 💭9주차➡️
  9. 💭10주차➡️
  10. 💭11주차➡️
  11. 💭12주차➡️
  12. 💭13주차➡️
  13. 💭14주차➡️

14주차

🔋 마지막 주차 🔋 2023.11.29

📖14주차 수업 자료


13주차

🔋 2023.11.22

📖13주차 수업 자료

📖13주차 수업 참고 사이트

📖13주차 과제


12주차

🔋 2023.11.15

📖12주차 수업 자료


11주차

🔋 2023.11.08

📖11주차 수업 자료

💭 설치
  • npx create-react-app my-app --template typescript

  • npm install @types/react @types/react-dom

💭 TypeScript with React Components
  • React로 타입스크립트를 작성하는 것은 자바스크립트를 작성하는 것과 비슷합니다.

  • 컴포넌트로 작업할 때 가장 큰 차이점은 컴포넌트의 props에 타입을 제공할 수 있다는 점입니다.

interface MyButtonProps {
  title: string;
  disabled: boolean;
}

function MyButton({ title, disabled }: MyButtonProps) {
  return <button disabled={disabled}>{title}</button>;
}

export default function MyApp() {
  return (
    <div>
      <h1>환영합니다.</h1>
      <MyButton title="버튼" disabled={true} />
    </div>
  );
}

📖실습1

📖실습2


10주차

🔋 2023.11.01

📖10주차 수업 자료

📖참고 자료

💭 일반적인 Generic Type 사용
function identity<Type>(arg: Type): Type {
  return arg;
}

let myIdentity = identity;

const data = myIdentity("dealim");
💭 예제
const users = [
    { id: 1, name: '홍길동' },
    { id: 2, name: '김선달' }
];

const products = [
    { id: 'a', title: '셔츠' },
    { id: 'b', title: '모자' }
];

function getUser(id) {
    return users.find(user => user.id === id);
}

function getProduct(id) {
    return products.find(product => product.id === id);
}

function addUser(user) {
    users.push(user);
}

function addProduct(product) {
    products.push(product);
}
💭 리팩토링
interface User {
    id: number;
    name: string;
}

interface Product {
    id: string;
    title: string;
}

const users: User[] = [
    { id: 1, name: '홍길동' },
    { id: 2, name: '김선달' }
];
const products: Product[] = [
    { id: 'a', title: '셔츠' },
    { id: 'b', title: '모자' }
];

function getUser(id: number): User | undefined {
    return users.find(user => user.id === id);
}

function getProduct(id: string): Product | undefined {
    return products.find(product => product.id === id);
}

function addUser(user: User): void {
    users.push(user);
}

function addProduct(product: Product): void {
    products.push(product);
}
💭 generic 사용
interface User {
    id: number;
    name: string;
}

interface Product {
    id: string;
    title: string;
}

const users: User[] = [
    { id: 1, name: '홍길동' },
    { id: 2, name: '김선달' }
];
const products: Product[] = [
    { id: 'a', title: '셔츠' },
    { id: 'b', title: '모자' }
];


interface Identifiable {
    id: string|number;
}

function getEntity<T extends Identifiable>(id: Identifiable, entities: T[]): T | undefined {
	
    return entities.find(entity => entity.id === id);
}

function addEntity<T extends Identifiable>(entity: T, entities: T[]): void {
    entities.push(entity);
}

const retrievedUser = getEntity(1, users);
const retrievedProduct = getEntity('a', products);

addEntity({ id: 3, name: 'Charlie' }, users);
addEntity({ id: 'c', title: 'Shoes' }, products);

9주차

🔋 2023.10.25

📖9주차 수업 자료

💭 null and undefined
  • 타입스크립트에서도 위의 두 값을 의미하는 타입이 존재하며 이 타입들이 동작하는 방식은 strictNullChecks 옵션의 사용 여부에 따라 달라집니다.
💭 strictNullChecks off
  • strictNullChecks를 끄면 null이거나 undefined값에 정상적으로 액세스할 수 있으며, nullundefined은 모든 유형의 프로퍼티에 할당할 수 있습니다.
function greet(name?: string) {
    // 'name'은 string 또는 undefined 일 수 있습니다.
    return "Hello, " + name.toUpperCase();
}
💭 strictNullChecks on
  • strictNullChecks를 켜면 값이 null이거나 undefined인 경우 해당 값에 메서드나 속성에 접근하기 전에 값을 테스트해야 합니다.
function greet(name?: string) {
    // 'name'은 string 또는 undefined 일 수 있습니다.
    return "Hello, " + name.toUpperCase();
}
💭 on-null Assertion Operator (Postfix !)
  • 타입스크립트에는 직접적인 체크 없이 타입에서 nullundefined을 제거하는 특별한 구문도 있습니다.

  • 표현식 뒤에 ! 을 사용하면 사실상 값이 nullundefined 이 아니라는 것을 의미합니다.

function liveDangerously(x?: number | null) {
  // No error
  console.log(x!.toFixed());
}
💭 Generic Type
  • C# 및 Java와 같은 언어에서 재사용 가능한 컴포넌트를 만들기 위한 기능 중 하나는 generics입니다.

  • 이는 단일 타입이 아닌 다양한 타입에서 작동할 수 있는 컴포넌트를 만들 수 있는 기능입니다.

function identity(arg: string|number): string|number {
  return arg;
}

let id = identity("dealim"); //let id: string | number
function identity<Type>(arg: Type): Type {
  return arg;
}

let id = identity<string>("dealim"); //let id: string
let id2 = identity<number>(52); //let id: number
let id3 = identity<boolean>(true); //let id: boolean

let nid = identity("dealim"); //let id: string
let nid2 = identity(52); //let id: number
let nid3 = identity(true); //let id: boolean
  • 해당 함수를 호출할때는 두가지 방법으로 호출이 가능합니다.
  1. 인수 호출 전 <> 안에 캡쳐할 타입을 명시적으로 선언하기
  2. 평소대로 호출하고 인수값을 바탕으로 typescript가 타입을 추론하도록 하기

중간고사

📖1주차 수업 자료

📖2주차 수업 자료

📖3주차 수업 자료

📖4~6주차 수업 자료

📖중간고사

📖중간고사(코드)

🏃시험 관련내용

  • 수요일 오전 10시 ~ 10시50분

  • 객관식 + 주관식 문제

  • 주관식 : 예제코드 빈칸 채우기, 코드 해석 1문제(동작 로직) -> 어떤걸 인수로 받는지 등등..

  • 리펙토링 : 코딩 컨벤션, 백틱, 템플릿 스트링, 디스트럭처링

  • 문항: 20문제

❗실습 문제들

  • 🔥 7주차
  1. 문제 1번
  • 실습1에서 CRUD 함수를 추가해보세요.

  • addStudent(student) -> student를 data에 추가

  • updateStudent(student) -> student 객체 안의 id를 기반으로 data 업데이트

  • seletctStudent(id) -> 해당 id를 가진 student 리턴

  • deleteStudent(id) -> 해당 id를 가진 student 삭제

  • 🔥 6주차

  1. 문제 1번

문제 1

  • 위 링크의 데이터 구조를 파악하고 type을 정의해보세요.

  • type, interface 사용

  • 리터럴 타입 사용

  • eslint 체크

  1. 문제 2번

문제 2

  • 위 링크의 데이터를 바탕으로 타입을 정의해보세요.

  • type, interface 사용

  • 리터럴 타입 사용

  • eslint 확인

  • 🔥 5주차

  1. 문제 1번

문제 1

  • Type Aliases 를 사용하여 위의 코드를 리펙토링해 보세요.
  • Interfaces를 사용하여 위의 코드를 리펙토링해 보세요.
  1. 문제 2번
  • 실습1에서 만든 코드에서 추가로 printAdminUserInfo 함수 구현
  • 해당 함수에서는 기존의 User정보에 role이라는 컬럼을 추가해서 출력
  • 기존의 Interface, type을 확장
  1. 문제3
  • 위 링크에서 포함된 데이터 세트에 대한 타입과 인터페이스를 지정하세요.

  • 그리고 강아지 또는 고양이만 console로 출력하는 함수를 만들어 보세요.

  • printData("dog")

  • printData("cat")

  1. 문제4
  • 지금까지 배운 내용을 바탕으로 지난시간에 진행했던 실습을 리펙토링 해 보세요.

  • type 또는 interface 사용

  • literal types 적용

  • 🔥 4주차

const data = [{
    "id": "p1",
    "name": "사과",
    "price": 1500,
    "stock": 10,
    "category": "식품",
    "discount": "10%"
  },
  {
    "id": "p2",
    "name": "노트북",
    "price": 1500000,
    "stock": 5,
    "category": "전자제품",
    "spec": "i7, 16GB RAM"
  },
  {
    "id": "p3",
    "name": "티셔츠",
    "price": 20000,
    "stock": 20,
    "category": "의류",
    "size": "M"
  },
  {
    "id": "p4",
    "name": "식빵",
    "price": 2500,
    "stock": 30,
    "category": "식품",
    "discount": 500
  },
  {
    "id": "p5",
    "name": "휴대폰",
    "price": 1000000,
    "stock": 10,
    "category": "전자제품",
    "discount": "5%"
}]

문제 1

  • 🔥 3주차
  1. 위 함수의 문제점을 찾아보세요. 위 함수가 문제가 발생하는 케이스를 작성하고 해결하기 위해서 어떻게 해야할지 코드를 수정해보세요.
function calculateAverage(scores: number[]) {
  let total = 0;
  let count = 0;
  for (const score of scores) {
    if (score) {
      total += score;
      count++;
    }
  }
  return total / count;
}
  1. 위 코드에서
function printBoard(result: any) {
  console.log(result)
}
  • 이 부분만 수정해서 아래와 같이 출력되도록 수정해보세요. 그리고 result: any 부분을 아래의 출력에 필요한 데이터만 받도록 처리하고 type 선언을 해주세요.
function printBoard(result: any) {
  console.log(result)
}

fetch('https://static-contents-serve.s3.ap-northeast-2.amazonaws.com/response.json').then((result)=>{
  return result.json()
}).then(list => {
  list.forEach((data: any)=>{
    printBoard(data)
  })
}).catch(err => {
  console.log(err)
});

6주차

🔋 2023.10.04

📖6주차 수업 자료

📂Literal Types

  • typescript에서는 string이나 number와 같은 타입 뿐만 아니라 값 자체를 의미하는 리터럴 타입도 정의할 수 있습니다. 이러한 리터럴 타입정의하는 방법과 함께 타입스크립트javascript에서 변수를 선언하는 방식에 따른 동작을 이해할 필요가 있습니다.
let changingString = "Hello World";
changingString = "안녕하세요.";
// 위에서 changingString은 가능한 모든 스트링을 나타낼 수 있기 때문에
// 타입스크립트에서는 아래와 같이 인식합니다.
changingString; // let changingString: string

const constString = "Hello World";
// constString은 오로지 "Hello World"라는 문자열만을 의미합니다.
// 타입스크립트에서는 아래와 같이 인식합니다.
constString;   //  const constString: "Hello World"
let x: "hello" = "hello";
x = "hello"; // 정상동작
x = "howdy"; // 에러
Type '"howdy"' is not assignable to type '"hello"'.Type '"howdy"' is not assignable to type '"hello"'.
function printText(s: string, alignment: "left" | "right" | "center") {
  // ...
}
printText("안녕하세요.", "left");

printText("반갑습니다.", "centre");
Argument of type '"centre"' is not assignable to parameter of type '"left" | "right" | "center"'.Argument of type '"centre"' is not assignable to parameter of type '"left" | "right" | "center"'.
function compare(a: string, b: string): -1 | 0 | 1 {
  return a === b ? 0 : a > b ? 1 : -1;
}
interface Options {
  width: number;
}
function configure(x: Options | "auto") {
  // ...
}
configure({ width: 100 });

configure("auto");

configure("automatic");
Argument of type '"automatic"' is not assignable to parameter of type 'Options | "auto"'.Argument of type '"automatic"' is not assignable to parameter of type 'Options | "auto"'.

📂Literal Inference

const obj = { counter: 0 };
obj.counter = 1;
  • TypeScript는 이전에 0이었던 필드에 1을 할당하는 것을 오류라고 가정하지 않습니다. (const임에도 불구하고) 다르게 말하면, obj.counter에는 0이 아닌 타입인 number로 추론합니다.
declare function handleRequest(url: string, method: "GET" | "POST"): void;

const req = { url: "https://example.com", method: "GET" };
handleRequest(req.url, req.method);

Argument of type 'string' is not assignable to parameter of type '"GET" | "POST"'.Argument of type 'string' is not assignable to parameter of type '"GET" | "POST"'.Try
  • 위의 예제에서 req.method는 "GET"이 아닌 string으로 추론됩니다. req를 생성하고 handleRequest를 호출하는 사이에 “안녕하세요"와 같은 다른 문자열을 req.method에 할당할 수 있기 때문에 TypeScript는 이 코드에 오류가 있는 것으로 간주합니다.

  • 이 문제를 해결하기 위해 두가지 방법을 사용 할 수 있습니다.

  1. 둘중 하나의 위치에 as를 통해 명시적으로 타입을 지정하는 방법이 있습니다.
// Change 1:
const req = { url: "https://example.com", method: "GET" as "GET" };
// Change 2
handleRequest(req.url, req.method as "GET");
  • Change 1은 "req.method가 항상 리터럴 타입 "GET"을 갖도록 하여 이후 해당 필드에 "안녕하세요"와 같은 다른 문자열을 할당할 수 없도록 하겠습니다."를 의미합니다.

  • Change 2는 "req.method가 "GET" 값을 갖습니다."를 의미합니다.

  1. as const 를 이용하여 req 객체 자체를 type literals로 고정합니다.
const req = { url: "https://example.com", method: "GET" } as const;
handleRequest(req.url, req.method);

📖6주차 과제 1

📖6주차 과제 2

📖6주차 과제 3


5주차

🔋 2023.09.27

📖5주차 수업 자료

📂Type Alias

  • type alias는 타입에 대한 이름을 지정하여 재 사용 가능하도록 하는 구문입니다.
type Point = {
  x: number;
  y: number;
};

function printCoord(pt: Point) {
  console.log("The coordinate's x value is " + pt.x);
  console.log("The coordinate's y value is " + pt.y);
}

printCoord({ x: 100, y: 100 });
  • 객체 타입은 위와 같이 type을 선언하여 사용 할 수 있습니다.

  • printCoord의 파라미터 값에 타입 어노테이션을 이용해 pt에 대한 타입을 지정했던 방식과는 달리 상단에 type alias를 선언해서 pt에 지정해주는 방식을 사용함으로 써 Point라는 타입을 재사용 할 수 있도록 처리했습니다.

  • 유니온 타입의 경우도 아래와 같이 사용 가능합니다.

type ID = number | string;

📂Interfaces

  • 인터페이스는 type의 이름을 지정하는 또 다른 방법입니다.
interface Point {
  x: number;
  y: number;
}

function printCoord(pt: Point) {
  console.log("The coordinate's x value is " + pt.x);
  console.log("The coordinate's y value is " + pt.y);
}

printCoord({ x: 100, y: 100 });

📂Type Aliases 와 Interfaces의 차이점

// 1. 병합
interface User {
  name: string;
}
interface User {
  age: number;
}
const userInfo: User = { name: "철수", age: 22 }; // No error


type UserType = { // Error: Duplicate identifier 'UserType'.
   name: string;
};
type UserType = { // Error: Duplicate identifier 'UserType'.
   age: number;
};


// 2. 확장
interface Animal {
  sound: string;
}
interface Dog extends Animal {
  breed: string;
}
class MyDog implements Dog {
  sound = "멍멍";
  breed = "진돗개";
}
const dog: Dog = {
  sound: "왈왈",
  breed: "치와와"
}


type AnimalType = {
  sound: string;
};
type DogType = AnimalType & {
  breed: string;
};

// 3. Union, Intersection (확장)

// interface Button = PrimaryButton | SecondaryButton;  // Error

type PrimaryButton = { label: string, primary: true };
type SecondaryButton = { label: string, primary: false };

type ButtonType = PrimaryButton | SecondaryButton;

// 4. 처리 가능한 속성
// interface ComputedProps {  // Error
//   [key: `prop_${string}`]: string;
// }

type ComputedPropsType = {
  [key: `sound_${count}`]: string;
};
interface User {
  id: string;
  name: string;
}

type ID = string | number;
type AnimalOrID = Animal | ID;

📖5주차 과제 1

📖5주차 과제 2

📖5주차 과제 3

📖5주차 과제 4


4주차

🔋 2023.09.20

📖4주차 수업 자료

📂Type Alias

  • type alias는 타입에 대한 이름을 지정하여 재 사용 가능하도록 하는 구문입니다.
type Point = {
  x: number;
  y: number;
};

function printCoord(pt: Point) {
  console.log("The coordinate's x value is " + pt.x);
  console.log("The coordinate's y value is " + pt.y);
}

printCoord({ x: 100, y: 100 });
  • 객체 타입은 위와 같이 type을 선언하여 사용 할 수 있습니다.

  • printCoord의 파라미터 값에 타입 어노테이션을 이용해 pt에 대한 타입을 지정했던 방식과는 달리 상단에 type alias를 선언해서 pt에 지정해주는 방식을 사용함으로 써 Point라는 타입을 재사용 할 수 있도록 처리했습니다.

  • 유니온 타입의 경우도 아래와 같이 사용 가능합니다.

type ID = number | string;

📂Interfaces

  • 인터페이스는 type의 이름을 지정하는 또 다른 방법입니다.

4주차 과제 1

📖4주차 과제 1

const data = [{
    "id": "p1",
    "name": "사과",
    "price": 1500,
    "stock": 10,
    "category": "식품",
    "discount": "10%"
  },
  {
    "id": "p2",
    "name": "노트북",
    "price": 1500000,
    "stock": 5,
    "category": "전자제품",
    "spec": "i7, 16GB RAM"
  },
  {
    "id": "p3",
    "name": "티셔츠",
    "price": 20000,
    "stock": 20,
    "category": "의류",
    "size": "M"
  },
  {
    "id": "p4",
    "name": "식빵",
    "price": 2500,
    "stock": 30,
    "category": "식품",
    "discount": 500
  },
  {
    "id": "p5",
    "name": "휴대폰",
    "price": 1000000,
    "stock": 10,
    "category": "전자제품",
    "discount": "5%"
  }]

function printProductInfo(product: {
  id: string;
  name: string;
  price: number;
  stock: number;
  category: string;
  discount?: string | number;
  spec?: string;
  size?: string;
}) {
  const { id, name, price, stock, category, discount, spec, size } = product;

  let discountedPrice;

  if (typeof discount === 'string') {
    const discountPercentage = parseInt(discount, 10);
    discountedPrice = price - (price * discountPercentage / 100);
  } else if (typeof discount === 'number') {
    discountedPrice = price - discount;
  } else {
    discountedPrice = price;
  }

  const TotalPrice = price.toLocaleString();
  const TotalDiscountedPrice = discountedPrice.toLocaleString();

  let result = `ID: ${id}, 이름: ${name}, 가격: ${TotalPrice}원, 할인가: ${TotalDiscountedPrice}원, 재고: ${stock}, 카테고리: ${category}`;

  if (spec !== undefined) {
    result += `, 스펙: ${spec}`;
  }

  if (size !== undefined) {
    result += `, 사이즈: ${size}`;
  }

  return result;
}

for (const product of data) {
  const productInfo = printProductInfo(product);
  console.log(productInfo);
}

3주차

🔋 2023.09.13

📖3주차 수업 자료

📂일반적인 유형 (Object, Union)

Object Types

  • 객체 타입을 타입스크립트에서 정의하는 법
function printUserName(name: string){ 
	console.log(name)
}

function printCoordinate(pt: {x: number, y: number}){
	console.log(`x 좌표 ${pt.x}`);
	console.log(`y 좌표 ${pt.y}`);
}

printCoordinate({ x: 3, y: 7 });
  • 함수 파라미터에 두개의 속성이 있는 타입을 number로 정의했습니다.

  • 명시적으로 타입을 지정하지 않을 경우 any 타입으로 지정됩니다.

  • 이때, noImplicitAny 설정이 되어있다면 에러가 발생하고, any 타입으로 가정하여 에러가 발생하지않습니다.

Optional Properties

  • 객체 타입을 지정할 때 경우에 따라 일부 속성값은 들어갈 수도 있고, 들어가지 않을 수도 있는 선택사항일수도 있습니다.

  • 그럴 경우에는 해당 속성 값의 바로 뒤에 ?를 넣어서 표현

function printUser(obj: { name: string, age?: number }, ) {
	if(!obj) console.log(`아무런 정보가 없습니다.`);
	else{
		console.log(`Name: ${obj.name}`);
		if (obj.age) console.log(`Age: ${obj.age}`);
	}
}
printUser();
printUser({name: "홍길동"});
printUser({name: "김길동", age: 21});

자바스크립트에서 ?를 사용한 문법

Optional Chaining : ?.

  • Optional Chaining은 객체의 속성이나 배열의 요소, 함수의 리턴값이 null 또는 undefined일 경우에 안전하게 접근할 수 있게 해주는 JavaScript 문법입니다.

Optional Chaining을 사용하지 않은 경우

function printCity(obj: { name: string; address?: { city: string }}) {
	console.log(`Name: ${obj.name}`);

	if( obj.address & obj.address.city) {
		console.log(`City: ${obj.address.city}`);
	}
}

printCity({ name: "홍길동" });
printCity({ name: "김길동", address: { city: "서울" } });

Optional Chaining을 사용한 경우

function printCityO(obj: { name: string; address?: { city: string }}) {
	console.log(`Name: ${obj.name}`);
	// address에 city값이 있을 경우 진행하고 없을 경우 "알수없음" 출력
	console.log(`City: ${obj.address?.city || "알수없음"}`);
}

printCity({ name: "홍길동" });
printCity({ name: "김길동", address: { city: "서울" } });

Temary Operator : ? :

  • Temary Operator는 조건 ? 참일때 리턴 : 거짓일때 리턴 형식으로 if문을 대신하여 사용할 수 있는 연산자입니다.
function printUser(obj: { name: string; age?: number }){
	console.log(`Name: ${obj.age}`);
	if(obj.age) {
		console.log(`Age: ${obj.age}`);
	}else{
		console.log("Age: UnKnown");
	}
	// const result = obj.age ? obj.age : 'Unknown';
	// console.log(result)
}

printCity({ name: "홍길동" });
printCity({ name: "김길동", age: 21 });

Temary Operator 사용 코드

function printUser(obj: { name: string; age?: number }) {
  console.log(`Name: ${obj.name}`);
  console.log(`Age: ${obj.age ? obj.age : 'Unknown'}`);
}

printUser({ name: "홍길동" });  // Output: "Name: 홍길동", "Age: Unknown"
printUser({ name: "김길동", age: 21 });  // Output: "Name: 김길동", "Age: 21"

Union Types

Defining a Union Type

  • 타입을 결합하는 방법중 하나는 union type입니다. union type은 두개 이상의 다른 타입으로 구성된 타입으로 해당 타입중 하나가 될 수 있는 것을 의미합니다. 이러한 타입들을 유니온의 각 member라고 합니다.

  • string 또는 number가 될 수 있는 타입을 선언할 수 있습니다.

function printId(id: number | string) {
  console.log(`당신의 ID: ${id}`);
}

printId(101);
printId("202");
printId({ myID: 22342 });

Working with Union Types

function printId(id: number | string) {
  console.log(`당신의 ID: ${id.toUpperCase()}`);
}

printId("202");
  • 타입스크립트에서 string | number 로 유니온 타입을 사용 할 경우 해당 함수 내부에서는 두 타입 모두가 허용하는 속성과 메서드만 사용 할 수 있습니다.

  • 이런 상황에서의 해결책은 javascript 코드를 기반으로 타입스크립트가 해당 타입을 ‘추론’ 할 수 있도록 명시적으로 처리하는 것입니다.

function printId(id: number | string) {
  if (typeof id === "string") {
    console.log(`당신의 ID: ${id.toUpperCase()}`);
  } else {
    console.log(id)
  }
}

printId("202");

javascript의 비교 연산자

&& 연산자 (AND 연산자), || 연산자 (OR 연산자)

  • && 연산자는 두 피연산자가 모두 true일 경우 true를 반환합니다. 첫 번째 피연산자가 false이면 두 번째 피연산자는 체크하지 않습니다. (short-circuit evaluation - 단축평가계산)

  • 좀 더 정확하게 표현하면 첫번째 피연산자가 Falsy이면 첫번째 피연산자 값을 리턴하고 모두 Truthy 면 마지막 피연산자 값을 리턴합니다.

  • || 연산자는 두 피연산자 중 하나라도 true일 경우 true를 반환합니다. 첫 번째 피연산자가 true이면 마찬가지로 두 번째 피연산자는 평가되지 않습니다.

  • 여기도 좀 더 정확하게 표현하면 첫번째 피연산자가 Truthy면 첫번째 피연산자를 리턴하고 둘 다 Falsy면 마지막 피연산자를 리턴합니다.

let isAccountActive = true;
let isEmailVerified = true;

if (isAccountActive && isEmailVerified) {
  console.log("로그인 성공!");
} else {
  console.log("로그인 실패!");
}

if (!isAccountActive || !isEmailVerified) {
  console.log("로그인 실패!");
} else {
  console.log("로그인 성공!");
}
let isConnected = false;
function fetchData() {
  console.log('데이터를 가져옵니다.');
	return true
}

if (isConnected && fetchData()) {
  console.log('데이터 조회 성공');
}
let age = 25;
let isAdult = (age >= 18) && "해당 사용자는 성인입니다.";

console.log(isAdult);

age = 15;
let message = (age >= 18) || "해당 사용자는 성인이 아닙니다.";

console.log(message);

Truthy, Falsy

  • JavaScript에서 "truthy""falsy"는 논리 연산자의 피연산자가 true 또는 false로 간주되는 경우를 설명하는 용어입니다. 이 차이를 이해하지 않고 각종 조건문을 사용하면 코드가 의도한대로 동작하지 않는 상황을 마주할 수 있습니다.

  • Javascript에서 아래의 조건절들은 모두 truthy로 취급됩니다.

if (true)
if ({})
if ([])
if (42)
if ("0")
if ("false")
if (new Date())
if (-42)
if (12n)
if (3.14)
if (-3.14)
if (Infinity)
if (-Infinity)
  • 정리하면 아래와 같은 값들이 truthy 입니다.
  1. **true`**
  2. 모든 숫자 (0을 뺀)
  3. 모든 문자열 (**'', “”**을 제외)
  4. 모든 객체와 배열 (빈 객체와 빈 배열 포함)
  • Javascript의 이러한 특징 때문에 아래와 같은 코드는 문제를 발생 시킬 수 있습니다.
const score = 0;

if (score) {
  console.log(`현재 스코어: ${score}`);
} else {
  console.log('서버로부터 스코어 값을 받아오지 못했습니다');
}
  • 위 코드의 경우 다양하게 해석 될 수 있지만 의도는 아래와 같다고 가정하겠습니다.
  1. score 값을 서버로부터 받아옴
  2. score 값 자체가 비어있을 수 있기에 if (score)를 통해 예외처리
  3. 현재 서버로부터 score의 값을 받아왔고 해당 값은 0
  • 따라서 위 코드의 결과는 현재 스코어: 0 이 출력되어야 합니다.
function welcomePeople(x: string[] | string) {
  if (Array.isArray(x) && x.length > 0) {
    console.log(`${x[0]}님 외 ${x.length}명의 방문을 환영합니다.`);
  } else {
    console.log(`${x}님 환영합니다.`);
  }
}
  • Array.isArray 메서드를 이용해 array타입인지 체크하고 각각의 케이스에 맞는 동작 코드를 수행하도록 처리되어 있습니다. 해당 코드에 따라 타입스크립트는 welcaomePeople에서 사용되는 유니온 타입들중 현재 x값이 array인지 string인지 체크 할 수 있습니다. 따라서 오류가 발생하지 않습니다.

  • 유니온 타입의 모든 맴버가 공통적으로 가지고 있는 메서드를 호출할 때 역시 별도의 오류 메세지를 발생시키지 않습니다. 대표적으로 slice 메서드는 string과 array 모두 가지고 있는 메서드입니다. 따라서 아래의 코드는 오류를 발생시키지 않습니다.

function getFirstThree(x: number[] | string) {
  return x.slice(0, 3);
}

console.log(getFirstThree("안녕하세요"));
console.log(getFirstThree([1,2,3,4,5,6,7,8]));

🏠3주차 과제

  1. 위 함수의 문제점을 찾아보세요. 위 함수가 문제가 발생하는 케이스를 작성하고 해결하기 위해서 어떻게 해야할지 코드를 수정해보세요. 타입스크립트 플레이그라운드(https://www.typescriptlang.org/play) 에서 코드를 작성하고 주석을 이용해 수정한 내용과 설명을 작성해주세요. 코드 링크 (Export -> Copy as Markdown Link)와 코드 화면을 캡쳐해서 첨부 후 제출하세요.
function calculateAverage(scores: number[]) {
  let total = 0;
  let count = 0;
  for (const score of scores) {
    if (score) {
      total += score;
      count++;
    }
  }
  return total / count;
}

📖3주차 과제 1

  • 답안
function calculateAverage(scores: number[]) {
  let total = 0;
  const count = scores.length;
  for (const score of scores) {
    total += score; 
    count++; 
  }
    return count === 0 ? '입력값X' : total / count;
}

console.log(calculateAverage([10, 20, 30, 0, 50, 60]));

📖3주차 과제 2

  • 답안
function printBoard(result: {
  RNUM_DESC: string;
  CATEGORY_NM: string;
  WRITE_DATE: string;
  HITS: number;
  FILE_CNT: number;
}) {

  const { RNUM_DESC, CATEGORY_NM, WRITE_DATE, HITS, FILE_CNT } = result;

  console.log(`${RNUM_DESC} - ${CATEGORY_NM} - ${WRITE_DATE} - 조회 ${HITS} - 첨부파일수 ${FILE_CNT}`)
}

fetch('https://static-contents-serve.s3.ap-northeast-2.amazonaws.com/response.json').then((result)=>{
  return result.json()
}).then(list => {
  list.forEach((data: any)=>{
    printBoard(data)
  })
}).catch(err => {
  console.log(err)
});

2주차

🔋 2023.09.06

📖2주차 수업 자료

📂원시 타입

  • 자바스크립트에서 주로 사용되는 원시 타입인 string, number, boolean은 타입스크립트에서 대응하는 타입이 있습니다.
  • string은 "Hello World"와 같은 문자열 값을 나타냅니다.
  • number는 42와 같은 숫자를 나타냅니다. 자바스크립트에는 정수에 대한 특별한 런타임 값이 없으므로 int나 float에 해당하는 값을 없으며 모든 것이 숫자입니다.
  • booleantrue, false두 값에 사용됩니다.
  • 원시 타입의 이름을 지정할때 String, Number와 같이 대문자로 시작하면 안됩니다.

📂원시 타입

  • 불변성
  • 메모리 효율성
  • 비교 시 값 자체를 비교 (Call by value)

📂래퍼 객체

  • 가변성
  • 객체로서 추가 메서드 및 프로퍼티를 가질 수 없음
  • 비교 시 참조를 비교 (Call by reference)

📂배열

  • 배열에 타입을 지정할 때는 그 배열을 구성하는 타입과 [] 표기를 사용합니다.

📂any

  • TypeScript의 any타입은 변수가 어떤 타입이든 될 수 있음을 나타냅니다. 일종의 프리패스권 또는 타입체크를 회피 하는 용도로 사용되다 보니 타입스크립트에 익숙하지 않은 개발자가 개발하는 과정에서 무분별하게 많이 쓰이게 되는 타입중 하나입니다.
  • 이름 그대로 모든 것을 허용하는 타입입니다.
  • 자바스크립트 프로젝트를 타입스크립트로 마이그레이션하는 과정이 아닌 한, 기본적으로 사용하지 않는 것을 권장

📂any는 아래와 같은 상황에서 사용될 수 있습니다.

  • 해당 라인이 문제가 없을것이라는 것을 확신 할수 있을 때
  • 타입정보가 없거나 미흡한 외부 라이브러리 등을 사용할 때
  • 실행시점에 타입이 결정되어서 타입을 미리 정할 수 없을 때

📂noImplicitAny

  • 기본적으로 타입스크립트에서 타입이 지정되어 있지 않은 변수들에 대해 문맥상 타입을 추정할 수 없다면 컴파일러에서는 any타입으로 가정합니다.

📂Type Annotations on Variables

  • 타입스크립트는 일반적인 언어에서 사용하는 int x = 0; 와 같은 “왼쪽에 타입을 정의하는” 스타일을 사용하지 않습니다. 타입 어노테이션은 항상 작성한 내용 다음에 오게 됩니다.

📂Functions

  • Parameter Type Annotations
  • 함수를 선언할 때 각 매개변수 뒤에 타입 어노테이션을 추가하여 함수가 허용하는 매개변수 타입을 선언할 수 있습니다.

  • 매개변수에 타입 어노테이션이 지정되면 해당 함수를 호출 할 때 인자값을 체크하게 됩니다.

📂Template strings - 백틱(``) 사용 문자열

  • 템플릿 스트링은 ES6에서 도입된 자바스크립트의 문자열 처리 방식중 하나입니다. 이 방식은 기존의 문자열을 다루기 위한 작은따옴표(‘’ ), 큰따옴표(“”) 대신 백틱(``) 이라는 문자를 사용하여 표현됩니다.

  • 이를 사용하면 두가지 장점을 가져갈 수 있습니다.

  1. 멀티라인 문자열: 백틱을 사용하면 문자열을 여러 줄에 걸쳐 쓸 수 있습니다.

  2. 문자열 삽입: ${}를 사용하여 문자열 안에 변수나 식을 삽입할 수 있습니다.

📂Return Type Annotations

📂Functions Which Return Promises

  • Promises를 리턴하는 함수에 타입 어노테이션을 달고 싶다면 Promise 타입을 사용해야 합니다.

📂Promise?

  • Promise는 비동기 작업의 최종 완료 또는 실패를 나타내는 객체입니다. 주로 서버와의 비동기 통신, 파일 읽기 등에 사용됩니다.

  • 비동기 작업 - 일반적으로 Javascript는 코드를 실행할때 위에서부터 아래의 순서대로 실행되게 됩니다.

📂Anonymous Functions

  • 익명 함수(또는 arrow function)의 경우도 비슷한 방식으로 타입 어노테이션을 달 수 있습니다.

📂익명함수?

  • 익명 함수(Anonymous Function)는 이름이 없는 함수를 의미합니다. 이러한 함수는 주로 함수의 인자로 전달되거나, 변수에 할당되어 사용됩니다.

  • 기본 문법 - JavaScript 및 TypeScript에서 익명 함수를 만드는 가장 기본적인 방법은 다음과 같습니다

  • 콜백 함수로 사용 - 익명 함수는 콜백 함수로도 많이 사용됩니다. 예를 들어, 배열의 map 메소드에 익명 함수를 전달할 수 있습니다

  • 화살표 함수 - ES6(ES2015) 이후, 화살표 함수(arrow function)라는 더 간단한 문법으로 익명 함수를 만들 수 있습니다

  • 즉시 실행 함수(IIFE) - 익명 함수는 즉시 실행되도록 할 수도 있습니다. 이를 즉시 실행 함수 표현식(IIFE, Immediately Invoked Function Expression)이라고 합니다.

  • 익명 함수는 함수의 이름을 명시하지 않기 때문에 디버깅이 어렵거나, 재귀 호출 같이 함수가 자기 자신을 호출해야 하는 상황에서는 사용이 제한될 수 있습니다. 그러나 간단한 로직을 변수에 할당하거나, 콜백으로 전달해야 하는 경우에는 코드를 간결하게 만들어 주는 장점이 있습니다.


1주차

📖1주차 수업 자료

🔋 2023.08.30

  • 💻오리엔테이션

  • 📃타입스크립트 개요

  • TypeScript는 Microsoft에서 개발한 자바스크립트의 확장 버전으로, 정적 타입 검사와 클래스 기반 객체 지향 프로그래밍을 추가한 언어입니다.
  • TypeScript는 큰 규모의 애플리케이션 개발에 적합하며, 오류를 줄이고 가독성과 유지보수성을 향상시키는데 도움을 줍니다.
  • 📜JavaScript와 TypeScript의 차이점
  • JavaScript는 동적 타입 언어입니다. 즉, 변수의 타입이 실행 시점에 결정되며, 변수의 타입을 변경할 수 있습니다.
  • TypeScript는 정적 타입 언어입니다. 변수의 타입은 선선 시점에 결정되며, 이후 변경할 수 없습니다. 이러한 특성은 개발자가 코드에서 오류를 더 쉽게 발견할 수 있도록 도와줍니다.
  • TypeScript는 클래스, 인터페이스, 제네릭 등과 같은 고급 객체 지향 프로그래밍 기능을 제공합니다.
  • 📃TypeScript를 사용해야 하는 이유
  1. 📋더 나은 에러 검출
  • 정적 타입 검사를 통해, 개발자는 컴파일 시점에 코드의 오류를 더 쉽게 발견할 수 있습니다.
  1. 📋개발 도구(IDE)의 지원 향상
  • 정적 타입 검사는 개발 도구에게 유용한 정보를 제공합니다. 이를 통해, 개발 도구는 더 나은 자동완성, 리팩토링 도구, 타입 검사 등을 제공할 수 있습니다.
  1. 📋향상된 문서화 및 코드 가독성
  • TypeScript의 타입 시스템은 코드를 작성하는 개발자 뿐만 아니라 다른 개발자에게도 변수나 함수가 어떤 값을 가지거나 변환해야 하는지 명확히 알려줍니다. 이러한 코드는 팀 작업이나 큰 프로젝트에서 특히 중요합니다.
  • TypeScript 설치 및 개발 환경 설정
  1. 📋Node.js 설치 : TypeScript는 Node.js 환경에서 실행되므로, 먼저 Node.js를 설치해야 합니다.
  2. 📋TypeScript 설치 : Node.js를 설치한 후에는, npm을 사용하여 TypeScript를 설치할 수 있습니다. 터미널에서 다음 명령어를 실행합니다. npm install -g typescript
  3. 📋텍스트 에디터 설치 : Vscode, subtime Text, Atom 등의 텍스트 에디터를 설치합니다. 이중 Vscode는 TypeScript에 대한 강력한 지원을 제공하므로, TypeScript 개발에 매우 적합합니다.
  • 컴파일 언어 & 인터프리터 언어 & 트랜스파일 언어

컴파일언어, 인터프리터언어

  • 컴파일러는 고수준 언어로 작성된 소스 코드를 한 번에 기계어나 다른 저수준 언어로 변환하는 프로그램입니다. 이 변환된 코드는 별도의 파일로 저장되며, 이 파일을 실행하며 프로그램을 동작시킵니다.

  • 📜컴파일 언어의 특징

  1. 실행 속도가 빠름
  2. 저수준 언어로 변환된 코드를 배포하기에 코드에 대한 보안성이 용이
  3. 컴파일 과정에서 전체 코드에 대한 문법 오류를 확인 할 수 있습니다.
  4. 코드의 규모가 크다면 컴파일이 오래 걸릴 수 있습니다.
  5. 실행하기 전 반드시 컴파일 과정을 거쳐야 하기에 디버깅이 불편합니다.
  6. 코드의 변경이 생기면 반드시 컴파일을 다시 해야 합니다.
  • 📜인터프리터는 고수준 언어로 작성된 소스 코드를 한 줄씩 읽어가면서 즉시 실행하는 프로그램입니다. 이는 별도의 변환과정이 없이 소스 코드를 직접 실행한다는 것을 의미합니다.

  • 📜인터프리터 언어의 특징

  1. 코드의 변경과 실행을 매우 빠르게 할 수 있다보니 디버깅 등이 쉽다.
  2. 실행 속도가 느릴 수 있습니다.
  3. 문법이 잘못된 코드가 있더라도 실행해서 해단 코드를 호출하기 전까지는 에러가 발생하지 않습니다.
  4. 소스코드 그대로 실행하다 보니 코드에 대한 보안이 부족합니다.
  • 패키지 매니저
  • 패키지 매니저는 코드 라이브러리를 관리해주는 도구를 의미합니다.

  • NPM : Node.js에서 사용되는 패키지 매니저

  • PIP : Python에서 사용되는 패키지 매니저

  • Maven, Gradle : Java에서 사용되는 빌드 도구 겸 패키지 매니저

  • NuGet : .NET에서 사용되는 패키지 매니저

  • apt, yum : Linux에서 사용되는 패키지 매니저

  • Homebrew : macOS에서 사용되는 패키지 매니저

  • 📜패키지 매니저를 사용해야 하는 이유

  1. 손쉬운 외부 패키지 설치
  • TypeScript 파일 다운로드, 설치, 각종 설정 -> npm install typescript
  1. 프로젝트에 사용된 패키지 버전의 관리
  • 설치된 패키지의 버전을 수동으로 추적해야 하고 이 정보를 별도 문서나 주석으로 남겨둬야 함 -> package.json과 같은 파일을 통해 자동으로 관리
  1. 패키지의 의존성 관리
  • 각 패키지의 의존성을 직접 파악하고 필요한 패키지를 버전에 맞게 하나씩 설치 -> 자동으로 해줌

About

타입스크립트

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published