2024.01.09 TIL - Deep Dive, TypeScript

명화·2024년 1월 9일

TIL

목록 보기
1/15
post-thumbnail

📚 [모던 자바스크립트 Deep Dive] 1장 프로그래밍


📝 1.1 프로그래밍이란?

컴퓨터에게 실행을 요구하는 일종의 커뮤니케이션이다.
0과 1밖에 알지 못하는 기계가 실행할 수 있을 정도로 정확하고 상세하게 요구사항을 설명하는 작업 (결과물: 코드)

  • 문제 해결 능력
    요구사항을 명확히 이해하는 것이 우선되어야 하며 복잡함을 단순하게 분해하고 자료를 정리하고 구분해야하며 순서에 맞게 행위를 배열해야 한다.

  • Computational thinking(컴퓨팅 사고)
    컴퓨터의 관점에서 문제를 사고해야 한다.
    논리적, 수학적 사고가 필요하며, 해결 과제를 작은 단위로 분해하고 패턴화해서 추출하며, 프로그래밍 내에서 사용될 모든 개념은 평가 가능하도록 정의해야 한다.

📝 1.2 프로그래밍 언어

문제 해결 능력을 바탕으로 정의된 문제 해결 방안은 컴퓨터가 이해할 수 있는 언어인 기계어로 명령을 전달해야한다.

기계어로 직접 명령을 전달하는 것 대신 "프로그래밍 언어"를 사용해 프로그램을 작성한 후, 그것을 컴퓨터가 이해할 수 있는 기계어로 변환하는 일종의 번역기를 이용한다.

일종의 번역기를 컴파일러(compiler) 혹은 인터프리터(interpreter)라고 한다.

프로그래밍 언어는 구문(syntax)의미(semantics)의 조합으로 표현된다.

📝 1.3 구문과 의미

문법에 맞는 문장을 구성하는 것은 물론 의미(semantics)를 가지고 있어야 언어의 역할을 충실히 수행할 수 있다.

결국 프로그래밍은 요구사항의 집합을 분석해서 적절한 자료구조와 함수의 집합으로 변환한 후, 그 흐름을 제어하는 것이다.


📘 TypeScript(타입스크립트)


📝 타입스크립트란?

타입스크립트 = 자바스크립트의 확장판
⇒ 자바스크립트에 타입을 더 안전하게 사용할 수 있는 기능을 추가한 것

//JavaScript(동적 타입 시스템)		//TypeScript (점진적 타입 시스템)
let a = 1;							let a:number = 1;
let b = 2;							let b:number = 2;
console.log(a+b);					console.log(a+b);

동적 타입 시스템 : 코드를 실행하면서 유동적으로 변수의 타입을 결정
점진적 타입 시스템 : 실행 전 검사를 통한 타입 안정성 확보, 자동으로 변수의 타입을 추론함

📝 타입스크립트를 사용하는 이유

자바스크립트는 애초에 간단한 프로그래밍을 위해 개발되어 유연한데, 간단하지 않은 복잡한 프로그램을 만드는데까지 활용되어 프로그램의 안정성을 떨어뜨리는 단점이 되어버렸다.
이런 자바스크립트의 문제접을 극복하기 위해서 자바스크립트의 기존 문법들과 매력은 그대로 유지한 채 안정성만 추가로 확보한 새로운 언어가 바로 타입스크립트이다.

📝 Type

원시타입 : number, string, boolean, null, undefined

let num: number = 123;
let str: string = "hello";
let bool: boolean = false;
let null: null = null;
let unde: undefined = undefined;

리터럴 타입 : 특정한 값 자체를 타입으로 지정하는 기능. 문자열 뿐만 아니라 숫자, 불리언 값도 리터럴 타입으로 만들 수 있음

type Fruit = "apple" | "banana" | "orange";
const f1: Fruit = "apple";
const f2: Fruit = "pineapple"; //Error

let num: 10 = 10;
let bool: true = true;

📝 배열

let numArr1: number[] = [1, 2, 3];
//또는
let numArr2:Array<number> = [1, 2, 3];

다양한 타입 요소를 갖는 배열 타입 정의

let multiArr: (number | string)[] = [1, "hello"]; //number타입 이거나 string타입

📝 튜플

자바스크립트에는 없는 타입스크립트의 특수한 타입으로 길이와 타입이 고정된 배열을 의미(인덱스별로 타입이 다를 때 사용)

let tup: [number, string, boolean] = [1, "hello", true];

📝 객체

//타입 별칭
type User = {
	id?: number; //선택적 프로퍼티(생략 가능)
    name: string;
    readonly age: number; //읽기전용 프로퍼티(수정 불가능)
};

let user: User = {
	id: 1,
    name: "홍길동",
    age: 20,
};

📝 열거형(Enum) 타입

자바스크립트에는 존재하지 않고 타입스크립트에서만 사용가능
비슷한 값들끼리 묶어 놓은 것(여러가지 값들에 각각 이름을 부여해 열거해두고 사용하는 타입)

enum Role {
  ADMIN = 0,
  USER = 1,
}

const user1 = {
  name: "홍길동",
  role: Role.ADMIN, //관리자
};

const user2 = {
  name: "아무개",
  role: Role.USER, // 회원
};

enum에 수동으로 값을 주지않으면 자동으로 0부터 1씩 증가하면서 할당된다.
만약 값을 변경하고 싶다면 시작하는 위치에 값을 직접 할당해주면 된다.

📝 any 타입

타입스크립트에서만 제공되는 타입으로 타입 검사를 받지 않는 타입 (하지만 최대한 사용하지 않는 것이 좋음)

let anyVar: any = 10;
anyVar = "hello";
anyVar = true;
anyVar = {};

📝 Unknown 타입

unknown 타입은 any 타입과 비슷하지만 보다 안전한 타입

let unkownVar: unknown;
unknownVar = "";
unknownVar = 1;
unknownVar = () => {};

📝 void

아무런 값도 반환하지 않는 함수의 반환값 타입을 정의할 때 사용

function func(): void {
	console.log("hello");
}

변수의 타입으로도 void 타입 지정이 가능하나 void 타입의 변수에는 undefiend 이외의 다른 타입의 값은 담을 수 없음

let a: void;
a = undefined;

📝 never 타입

에러를 반환하거나 영원히 끝나지 않은 함수의 타입을 정의할 때 사용

function func(): never {
	while(true) {}
}

function showError(): never {
  throw new Error();
}

📝 함수의 타입

어떤 타입의 매개변수를 받고, 어떤 타입의 값을 반환하는지 작성(함수의 반환값 타입은 자동으로 추론되기 때문에 타입 정의 생략 가능)

function func(a: number, b: number)~~: number~~ {
	return a + b;
}

화살표 함수 타입

const add = (a: number, b: number)~~: number~~ => a + b;

매개변수 기본값 설정
함수의 매개변수에 기본값이 설정되어있으면 타입이 자동으로 추론되기 때문에 타입 정의 생략 가능

function introduce(name = "홍길동") {
	console.log(`name: ${name}`);
}

선택적 매개변수 설정
매개변수의 이름 뒤에 물음표(?)를 붙여주면 선택적 매개변수가 되어 생략이 가능 (선택적 매개변수는 필수 매개변수 앞에 올 수 없음. 반드시 뒤에 배치해야 함!)

function introduce(name = "홍길동", age?: number) {
	console.log(`name: ${name}`);
    console.log(`age: ${age}`);
}
introduce("홍길동", 20);
introduce("홍길동");

나머지 매개변수
rest 매개변수는 나머지 매개변수라고 하며, 스프레드 연산자처럼 기호 '...'으로 표기
나머지 매개변수의 길이를 고정하고 싶으면 튜플 타입 사용

function getSum(...rest: number[]) {
	let sum = 0;
    rest.forEach((it) => (sum += it));
    return sum;
}

getSum(1, 2, 3);

📝 인터페이스

타입 별칭과 동일하게 타입에 이름을 지어주는 또 다른 문법 (타입 별칭은 동일한 스코프 내에 중복된 이름으로 선언X, 인터페이스는 가능)

interface Person {
	id?: number; //선택적 프로퍼티(생략 가능)
    name: string;
    readonly age: number; //읽기전용 프로퍼티(수정 불가능)
};

const person: Person = {
	id: 1,
    name: "홍길동",
    age: 20,
};

인터페이스 확장
interface 타입이름 extends 확장 할 타입이름 형태로 extends 뒤에 확장할 타입의 이름을 정의하면 해당 타입에 정의된 모든 프로퍼티를 다 가지고 오게 됩니다.

interface Animal {
  name: string;
  color: string;
}

interface Dog extends Animal {
  breed: string;
}

interface Cat extends Animal {
  isScratch: boolean;
}

📝 제네릭

함수나 인터페이스, 타입 별칭, 클래스 등을 다양한 타입과 함께 동작하도록 만들어주는 기능

제네릭(Generic) 함수 <>
모든 타입의 값을 다 적용할 수 있는 범용적인 함수

function func<T>(value: T): T {
	return value;
}

let num = func(10); //number타입이 들어갔으므로 T가 number 타입으로 추론, 반환값 또한 number 타입이 됨
let arr = func<[number, number, number]>([1, 2, 3]); //타입을 직접 명시하는 것도 가능

함수 이름 뒤에 꺽쇠(<>)를 열고 타입을 담는 변수인 타입 변수 T를 선언한다.
그리고 매개변수와 반환값의 타입을 T로 설정한다.
T에 어떤 타입이 할당될 지는 함수가 호출될 때 결정된다.

제네릭 인터페이스
인터페이스에 타입 변수를 선언하여 사용 가능

interface KeyPair<K, V> {
	key: K;
    value: V;
}

let keyPair: KeyPair<string, number> = {
	key: "key",
    value: 0,
};

let keyPair2: KeyPair<boolean, string[]> = {
	key: true,
    value: ["1"],
};

제네릭 인터페이스는 제네릭 함수와는 달리 변수의 타입으로 정의할 때 반드시 꺽쇠(<>)와 함께 타입 변수에 할당할 타입을 명시해주어야 한다.
그 이유는 제네릭 함수는 매개변수에 제공되는 값의 타입을 기준으로 타입 변수의 타입을 추론할 수 있지만 인터페이스는 마땅히 추론할 수 있는 값이 없기 때문이다.

2개의 댓글

comment-user-thumbnail
2024년 1월 10일

넌 할 수 있어~!

1개의 답글