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