본문 바로가기

카테고리 없음

Study_240624 ( TS 타입 및 간단한 성적표 만들기 + tsc 명령어 설명)

간단한 성적표 만들기

순서 : yarn init -y ( package.json 생성 )

-> tsc --init --rootDir ./src --outDir ./dist --esModuleInterop --module commonjs --strict true --allowJS true --checkJS true 입력 ( tsconfig.json 설정 하는 것 ) / 권한때문에 안 될 시 Set-ExecutionPolicy -Scope Process -ExecutionPolicy Bypass 입력으로 해당 폴더(위치)에서 권한 부여 가능

-> package.json에 코드 추가 (scripts부분임)

-> src폴더 생성 후 시작

-> yarn run build ( 프로젝트 빌드 , 컴파일 에러시 에러남 )

-> yarn run start ( 실행 )

{
  "name": "testTS",
  "version": "1.0.0",
  "main": "index.js",
  "license": "MIT",
  "scripts": {
    "start": "tsc && node ./dist/index.js",
    "build": "tsc --build",
    "clean": "tsc --build --clean"
  }
}
 
interface Student {
  name: string;
  age: number;
  scores: {
    korean: number;
    math: number;
    society: number;
    science: number;
    english: number;
  };
}

// 화살표 함수와 일반 함수 선언의 차이점
// 일반 함수 선언 : 함수내에서 this는 함수 호출 시 결정 / 함수 내부에서 arguments 객체 사용 가능
// 화살표 함수 : 자신만의 thi를 가지지 않고 정의된 범위의 this를 사용(렉시컬 스코프) / arguments객체를 가지지 않는 대신 필요 시 레스트 파라미더 사용 가능
// 용도 : 일반 함수는 주로 객체의 메서드나 생성자 함수 / 화살표는 콜백 함수나 간단한 함수 표현
function assignGrade(average: number): string {
  if (average >= 90) {
    return "A";
  } else if (average >= 80) {
    return "B";
  } else if (average >= 70) {
    return "C";
  } else if (average >= 60) {
    return "D";
  } else {
    return "F";
  }
}

// 당연하게도 화살표 함수로 바꿀 수 있음
const calculateAverage = (student: Student): number => {
  const sum =
    student.scores.korean +
    student.scores.math +
    student.scores.society +
    student.scores.science +
    student.scores.english;
  // Object.keys는 매개변수의 키를 String형태에 배열로 반환
  // ex) ["korean", "math", "society", "science", "english"]
  const average = sum / Object.keys(student.scores).length;
  return average;
};

function createStudent(
  name: string,
  age: number,
  // scores를 감싸지 않는 이유 -> 함수 호출 시 편하게 입력 가능
  korean: number,
  math: number,
  society: number,
  science: number,
  english: number
): Student {
  return {
    name,
    age,
    // 여기가 간단해지지만 함수 호출 시 아래의 키,밸류 페어를 가진
    // 상수를 선언 후 함수 호출 시 매개변수로 넘겨줘야함
    scores: {
      korean,
      math,
      society,
      science,
      english,
    },
  };
}
// scores를 감싼 함수
// function createStudent(
//   name: string,
//   age: number,
//   scores: {
//     korean: number;
//     math: number;
//     society: number;
//     science: number;
//     english: number;
//   }
// ): Student {
//   return {
//     name,
//     age,
//     scores,
//   };
// }
// 예시코드
// scores를 감싸지 않은 경우
// const student1 = createStudent("John Doe", 16, 85, 90, 78, 88, 92);
// scores를 감싼 경우
// const scores = { korean: 85, math: 90, society: 78, science: 88, english: 92 };
// const student2 = createStudent("Jane Doe", 16, scores);

// void 타입은 함수가 값을 반환(return)하지 않음
function printResult(student: Student): void {
  const average = calculateAverage(student);
  const grade = assignGrade(average);
  console.log(
    `${student.name} (${student.age}세) - 평균: ${average.toFixed(
      2
    )}, 학점: ${grade}`
  );
}

function main(): void {
  const spartan = createStudent("Spartan", 30, 95, 89, 76, 90, 97);
  printResult(spartan);
}

main();

 

타입 설명

boolean 예시 코드

주의할 점 : 보통 2가지의 상태 표현 시 사용 -> 3가지 이상은 enum이나 string 사용

function isValidPassword(password: string): boolean {
  return password.length >= 8;
}

const password = "q1w2e3r4!";
const valid = isValidPassword(password);

if (valid) {
  console.log("유효한 패스워드입니다!");
} else {
  console.log("유효하지 않은 패스워드입니다!");
}

 

number : 모든 숫자 표현 가능 ( 정수 , 실수 , 2,4,8진수 모두 표현 가능 ) / 예시 코드

function calculateArea(radius: number): number {
  return Math.PI * radius * radius;
}

const radius = 5;
const area = calculateArea(radius);
console.log(`반지름이 ${radius}인 원의 넓이: ${area}`);

 

string : `~` 백틱은 템플릿 리터럴임 / 예시 코드

function greet(name: string): string {
  return `안녕, ${name}!`;
}

const name = "Spartan";
const greeting = greet(name);
console.log(greeting);

 

배열 예시 코드

function calculateSum(numbers: number[]): number {
  let sum: number = 0;
  for (let i = 0; i < numbers.length; i++) {
    sum += numbers[i];
  }
  return sum;
}

const testScores: number[] = [90, 85, 78, 92, 88];
const sumScore = calculateSum(testScores);
console.log(`점수의 총합: ${sumScore}`);

 

튜플(tuple) : 서로 다른 타입의 원소를 순서에 맞게 가질 수 있는 특수한 형태의 배열

ex) 아래 코드는 일반 배열 타입이므로 오류가 남

const testScores: number[] = [90, 85, 78, 92, “88”];

튜플 예시 코드 -> push는 되지만 튜플 구조가 내부적으로 변경되니 정의된 타입과 갯수를 맞춰서 넣어야함

const person: [string, number, boolean] = ['Spartan', 25, false];
const person2: [string, number, boolean] = [25, 'Spartan', false]; // 오류!

 

enum : 열거형 데이터 타입 -> 다양한 상수를 보다 더 이해하기 쉬운 문자열 이름으로 접근하고 사용 가능함

-> 각 요소 값이 없다면 숫자 0부터 시작 / number 혹은 string 타입만 할당 가능

예시코드 -> 명확하게 관련된 상수 값들을 그룹화시 사용 추천 / 값의 수가 적거나 값들 사이 관계가 뚜렷하지 않으면 사용안하는게 좋음

enum UserRole {
  ADMIN = "ADMIN",
  EDITOR = "EDITOR",
  USER = "USER",
}

enum UserLevel {
  NOT_OPERATOR, // 0
  OPERATOR, // 1
}

function checkPermission(userRole: UserRole, userLevel: UserLevel): void {
  if (userLevel === UserLevel.NOT_OPERATOR) {
    console.log("당신은 일반 사용자 레벨이에요");
  } else {
    console.log("당신은 운영자 레벨이군요");
  }

  if (userRole === UserRole.ADMIN) {
    console.log("당신은 어드민이군요");
  } else if (userRole === UserRole.EDITOR) {
    console.log("당신은 에디터에요");
  } else {
    console.log("당신은 사용자군요");
  }
}

const userRole: UserRole = UserRole.EDITOR;
const userLevel: UserLevel = UserLevel.NOT_OPERATOR;
checkPermission(userRole, userLevel);

 

readonly 키워드 : TS키워드 -> 객체의 속성을 불변으로 만드는 키워드 -> 클래스 , 인터페이스 속성 변경X

예시 코드 -> class 내부에서 필드 선언 시 내부 속성에는 const , let 키워드 사용 안됨 , 타입만 지정 가능

class Person
  readonly name: string;
  readonly age: number;

  constructor(name: string, age: number) {
    this.name = name;
    this.age = age;
  }
}

const person = new Person('Spartan', 30);

console.log(person.name);  // 출력: 'Spartan'
console.log(person.age);   // 출력: 30

person.name = 'Jane';  // 에러: 'name'은 readonly 속성이므로 다시 할당할 수 없음
person.age = 25;       // 에러: 'age'은 readonly 속성이므로 다시 할당할 수 없음

 

any 타입 : 어떤 타입이든 저장 가능 ( JS의 object 타입과 같은 최상위 타입 ) , 슈퍼 타입임

예시 코드 -> TS를 쓰는건 타입 안정성 확보 위해서기때문에 any사용은 지양해야함

let anything: any;
anything = 5; // 최초에는 숫자를 넣었지만
anything = 'Hello'; // 문자열도 들어감
anything = { id: 1, name: 'John' }; // JSON도 들어감

 

unknown : any와 비슷하지만 더 안전함 -> 다른 타입의 변수에 할당 시 명시적으로 타입 확인 필요

예시 코드 -> as string 이런 코드를 Type Assertion ( 타입 단언 ) 이라고 함 / 그 외에도 typeof 키워드를 사용하여 타입을 미리 체크 후 unknown타입의 변수를 다른 타입의 변수에 할당 가능 -> 타입 단언이 더 좋긴함

let unknownValue: unknown = '나는 문자열이지롱!';
console.log(unknownValue); // 나는 문자열이지롱!

let stringValue: string;
stringValue = unknownValue; // 에러 발생! unknownValue가 string임이 보장이 안되기 때문!
stringValue = unknownValue as string;
console.log(stringValue); // 나는 문자열이지롱!

 

union : 여러 타입 중 하나를 가질 수 있는 변수 선언 시 사용 | 연산자를 사용하여 여러 타입 결합하여 표현

예시 코드

type StringOrNumber = string | number; // 원한다면 | boolean 이런식으로 타입 추가가 가능

function processValue(value: StringOrNumber) {
  if (typeof value === "string") {
    // value는 여기서 string 타입으로 간주됨
    console.log("String value:", value);
  } else if (typeof value === "number") {
    // value는 여기서 number 타입으로 간주됨
    console.log("Number value:", value);
  }
}

processValue("Hello");
processValue(42);

 

TS는 여러 타입을 하나의 변수로 해결하려 하지 않아도 됨!! 

 

아래는 명령어 관련 gpt 설명

명령어와 옵션들

  1. tsc --init:
    • tsc는 TypeScript 컴파일러입니다.
    • --init 옵션은 기본 tsconfig.json 파일을 생성합니다. 이 파일은 TypeScript 프로젝트의 설정을 정의하는 데 사용됩니다.
  2. --rootDir ./src:
    • rootDir 옵션은 소스 파일의 루트 디렉토리를 지정합니다. 여기서 ./src는 src 폴더를 프로젝트의 루트 디렉토리로 설정합니다.
    • TypeScript 컴파일러는 이 디렉토리를 기준으로 소스 파일을 찾습니다.
  3. --outDir ./dist:
    • outDir 옵션은 컴파일된 JavaScript 파일들이 출력될 디렉토리를 지정합니다. 여기서 ./dist는 dist 폴더를 출력 디렉토리로 설정합니다.
    • 컴파일된 파일들은 이 디렉토리에 저장됩니다.
  4. --esModuleInterop:
    • esModuleInterop 옵션은 ES 모듈의 import 구문을 CommonJS 모듈에서 호환 가능하게 합니다. 이는 디폴트 import를 사용하여 CommonJS 모듈을 가져올 때 유용합니다.
    • 이 옵션을 설정하면 TypeScript는 CommonJS 모듈을 가져올 때 __importDefault 헬퍼 함수를 사용합니다.
  5. --module commonjs:
    • module 옵션은 컴파일된 JavaScript 코드의 모듈 시스템을 지정합니다. 여기서 commonjs는 Node.js에서 사용하는 CommonJS 모듈 시스템을 설정합니다.
    • 이 옵션은 모듈 로딩 방식에 영향을 미칩니다.
  6. --strict true:
    • strict 옵션은 TypeScript의 엄격 모드(strict mode)를 활성화합니다. 엄격 모드는 TypeScript의 다양한 엄격한 타입 검사 규칙을 적용하여 코드를 더 안전하게 만듭니다.
    • 이 옵션은 여러 개의 개별 엄격 검사 옵션(strictNullChecks, strictFunctionTypes, strictPropertyInitialization 등)을 한꺼번에 설정합니다.
  7. --allowJS true:
    • allowJS 옵션은 TypeScript 컴파일러가 JavaScript 파일을 허용하도록 설정합니다. 이 옵션이 활성화되면 프로젝트에 포함된 JavaScript 파일도 컴파일 대상이 됩니다.
  8. --checkJS true:
    • checkJS 옵션은 TypeScript 컴파일러가 JavaScript 파일을 타입 체크하도록 설정합니다. allowJS와 함께 사용되며, TypeScript 코드처럼 JavaScript 코드도 타입 검사를 받게 됩니다.

tsc --init --rootDir ./src --outDir ./dist --esModuleInterop --module commonjs --strict true --allowJS true --checkJS true

 

이 명령어는 다음과 같은 설정으로 tsconfig.json 파일을 생성합니다:

  • 소스 파일의 루트 디렉토리를 ./src로 설정합니다.
  • 컴파일된 JavaScript 파일을 ./dist 디렉토리에 출력합니다.
  • ES 모듈의 import 구문을 CommonJS 모듈에서 호환 가능하게 합니다.
  • 컴파일된 JavaScript 코드의 모듈 시스템을 CommonJS로 설정합니다.
  • TypeScript의 엄격 모드를 활성화하여 더 강력한 타입 검사를 수행합니다.
  • JavaScript 파일을 허용하고, 이를 TypeScript 컴파일러가 타입 체크하도록 설정합니다.