16주차 TIL & 회고

강성일·2023년 7월 31일
0
post-thumbnail

🔥 feat: TIL 노트 추가


📌 Type 시스템
└ 명시적 정의(변수 선언 시 타입 정의)

let a: boolean = "x"
→ 🚫 boolean 타입에 string타입 할당 불가 알림
└ 변수만 생성(타입 추론)

let b = "hello"
→ b가 string 타입이라고 추론
b = 1
→ 🚫 string 타입에 number타입 할당 불가 알림

----------------------------------------------------------------------------

📌 Types of TS(기본)

✅ 배열: 자료형[]
✅ 숫자: number
✅ 문자열: string
✅ 논리: boolean
✅ optional

const player : {
    name: string,
    age?:number
} = {
    name: "nico"
}

❌ player.age가 undefined일 가능성 알림
if(player.age < 10) {
}

⭕ player.age가 undefined일 가능성 체크
if(player.age && player.age < 10) {
}?:앞에 붙이면 optional

✅ Alias(별칭) 타입
type Player = {
    name: string,
    age?:number
}

const player : Player = {
    name: "nico"
}

⭐ 함수에서는 어떻게 쓸까
type Player = {
    name: string,
    age?:number
}

function playerMaker1(name:string) : Player {
    return {
        name
    }
}

const playerMaker2 = (name:string) : Player => ({name})

const nico = playerMaker1("nico")
nico.age = 12

----------------------------------------------------------------------------

📌 Types of TS(part II)readonly 사용하기
type Player = {
    readonly name:string
    age?:number
}

const playerMaker = (name: string): Player => ({name})

const nico = playerMaker("nico")
🚫 nico.name = "aa"

const numbers: readonly number[] = [1, 2, 3, 4]
🚫 numbers.push(1)readonly가 있으면 최초 선언 후 수정 불가
    ⇒ immutability(불변성) 부여
        but, javascript에서는 그냥 배열

✅ Tuple
정해진 개수와 순서에 따라 배열 선언
const player: [string, number, boolean] = ["nico", 1, true]readonly도 사용가능 ⇒ readonly [...] 형태

✅ undefined, null, any
any: 아무 타입
undefined: 선언X 할당X
null: 선언O 할당X

----------------------------------------------------------------------------

📌 Types of TS(part III)unknown
let a:unknown

if(typeof a === 'number'){
    let b = a + 1
}
if(typeof a === 'string'){
    let b = a.toUpperCase()
}
🚫 let b = a + 1void
아무것도 return하지 않는 함수에서 반환 자료형
function hello() {
    console.log('x')
}
const a = hello()
🚫 a.toUpperCase()never
함수가 return하지 않을 때
function hello():never {
    throw new Error("zzz")
    🚫return "a"
}

function temp(name:string|number):never {
    if(typeof name === "string"){
        name
    } else if(typeof name === "number"){
        name
    } else {
        name
    }
}

if 안에서는 string형의 name 반환
else if 안에서는 number형의 name 반환
else 안에서는 never형의 name 반환
⇒ 즉, 제대로 인자가 전달되었다면 else로 올 수 없음

----------------------------------------------------------------------------

📌 Call Signatures

프로퍼티로 호출 가능한 것을 설명하려면 객체 타입에 Call Signature을 작성할 수 있습니다.
Call Signatures는 다음과 같이 함수의 매개 변수(parameter)와 반환 타입을 지정합니다.


─ 예시 ────────────────────────

type PizzaFunction = {
pizza: string;
(args: number): boolean;
};

function hello(fn: PizzaFunction) {
console.log(fn.pizza, fn(6));
}


https://www.typescriptlang.org/docs/handbook/2/functions.html#call-signatures

----------------------------------------------------------------------------

📌 Function Overloads

동일한 이름에 매개 변수와 매개 변수 타입 또는 리턴 타입이 다른 여러 버전의 함수를 만드는 것을 말합니다.
오버로드 signatures을 작성하여 "다양한 방식으로 호출할 수 있는 함수"를 지정할 수 있습니다.


─ 예시 ────────────────────────

type Add={
(a:number,b:number):number;
(a:number,b:number,c:number):number;
}

const add:Add=(a,b,c?:number)=>{
return a+b;
}
add(1,2)
add(1,2,3)


https://www.typescriptlang.org/docs/handbook/2/functions.html#function-overloads

----------------------------------------------------------------------------

📌 polymorphism(다형성)

❓poly란?
- many, serveral, much, multi 등과 같은 뜻
❓morphos란?
- form, structure 등과 같은 뜻
❗polymorphos = poly + morphos = 여러 다른 구조

concrete type
- number, boolean, void 등 지금까지 배운 타입

generic type
- 타입의 placeholder

─ 예시 ────────────────────────
type SuperPrint = { (arr: T[]): void }
type SuperReturn = { (arr: T[]): T }

const superPrint: SuperPrint = (arr) => {
    arr.forEach(i => console.log(i))
}
const superReturn: SuperReturn = (arr) => arr[0]

superPrint([1, 2, false, true])
console.log(superReturn([1, 2, 3, 4]))

----------------------------------------------------------------------------

📌 Generics

제네릭은 C#이나 Java와 같은 언어에서 재사용 가능한 컴포넌트를 만들기 위해 사용하는 기법입니다.
단일 타입이 아닌 다양한 타입에서 작동할 수 있는 컴포넌트를 생성할 수 있습니다.
(구체적인 타입을 지정하지 않고 다양한 인수와 리턴 값에 대한 타입을 처리할 수 있다.)
타입스크립트에서 제네릭을 통해 인터페이스, 함수 등의 재사용성을 높일 수 있습니다.


─ 예시 ────────────────────────

function identity< Type >(arg: Type): Type {
return arg;
}

// 제네릭 화살표 함수 (tsx기준)
const identity=< Type extends {} >(arg: Type):Type => {
return arg;
}

let output = identity< string >("myString"); // 첫 번째 방법
let output = identity("myString"); // 두 번째 방법
// 두 번째 방법은 type argument inference(타입 인수 유추)를 사용합니다., 컴파일러가 전달하는 인수 유형에 따라 자동으로 Type 값을 설정하기를 원합니다.


https://www.typescriptlang.org/docs/handbook/2/generics.html


💡 그렇다면 그냥 any를 넣는 것과 Generic의 차이는 무엇일까?

type SuperPrint = {
(arr: any[]): any
}

const superPrint: SuperPrint = (arr) => arr[0]

let a = superPrint([1, "b", true]);
// pass
a.toUpperCase();

-> any를 사용하면 위와 같은 경우에도 에러가 발생하지 않는다

type SuperPrint<T> = {
(arr: T[]): T
}

const superPrint: SuperPrint = (arr) => arr[0]

let a = superPrint([1, "b", true]);
// error
a.toUpperCase();

-> Generic의 경우 에러가 발생해 보호받을 수 있다
* Call Signature를 concrete type으로 하나씩 추가하는 형태이기 때문!

type SuperPrint = {
(arr: T[], x: M): T
}

const superPrint: SuperPrint = (arr, x) => arr[0]

let a = superPrint([1, "b", true], "hi");

위와 같이 복수의 Generic을 선언해 사용할 수 있다

----------------------------------------------------------------------------

📌 Classes

추상(abstract) 클래스
추상 클래스는 오직 다른 클래스가 상속받을 수 있는 클래스이다.
하지만 직접 새로운 인스턴스를 만들 수는 없다.


─ 예시 ────────────────────────

abstract class User{
constructor(
private firstname:string,
private lastname:string,
public nickname:string
){
abstract getNickname():void
}
}

class Player extends User{
// 추상 메서드는 추상 클래스를 상속받는 클래스들이 반드시 구현(implement)해야하는 메서드이다.
getNickname(){
console.log(this.nickname)
}
}


public: 모든 클래스에서 접근 가능
private: 해당 클래스 내에서만 접근 가능 (자식 클래스에서도 접근 불가)
protected: 해당 클래스와 자식 클래스에서 접근 가능

https://www.typescriptlang.org/docs/handbook/2/classes.html

----------------------------------------------------------------------------

📌 Static Members

클래스에는 static 멤버가 있을 수 있습니다.
이 멤버는 클래스의 특정 인스턴스와 연결되지 않습니다. 클래스 생성자 객체 자체를 통해 액세스할 수 있습니다.
static 멤버는 동일한 public, protectedprivate 과 함께 사용할 수도 있습니다.


─ 예시 ────────────────────────

class MyClass {
static x = 0;
static printX() {
console.log(MyClass.x);
}
}
console.log(MyClass.x);
MyClass.printX();


https://www.typescriptlang.org/docs/handbook/2/classes.html#static-members

----------------------------------------------------------------------------

Interfaces

객체의 모양을 특정해주기 위해 사용합니다. (type도 그러하나 범용성이 더 넓다.)
여기서는 firstName 및 lastName 필드가 있는 객체를 설명하는 인터페이스를 사용합니다.


─ 예시 ────────────────────────

interface Person {
firstName: string;
lastName: string;
}


https://www.typescriptlang.org/docs/handbook/
typescript-tooling-in-5-minutes.html#interfaces

----------------------------------------------------------------------------

📌 implements

implements을 사용하여 클래스가 특정 인터페이스를 충족하는지 확인할 수 있습니다.
클래스를 올바르게 구현하지 못하면 오류가 발생합니다.
implements 절은 클래스가 인터페이스 유형으로 처리될 수 있는지 확인하는 것입니다.
클래스의 유형이나 메서드는 전혀 변경하지 않습니다.
또한 클래스는 여러 인터페이스를 구현할 수도 있습니다. 클래스 CA, B를 구현합니다.


─ 예시 ────────────────────────

ex) class C implements A, B { }

interface Pingable {
ping(): void;
}

// Sonar클래스는 Pingable인터페이스를 implement했기 때문에
Pingable가 가진 ping메서드를 구현해줘야 합니다.

class Sonar implements Pingable {
ping() {
console.log("ping!");
}
}


https://www.typescriptlang.org/docs/handbook/2/classes.html#implements-clauses

----------------------------------------------------------------------------

💡 Type Aliases과 Interfaces의 차이점

Type Aliases과 인터페이스는 매우 유사하며 많은 경우 자유롭게 선택할 수 있습니다.

인터페이스의 거의 모든 기능은 type에서 사용할 수 있으며,
주요 차이점은 type을 다시 열어 새 속성을 추가할 수 없는 것입니다.

반면 인터페이스는 항상 확장 가능합니다.

결론: 대부분의 경우 개인 취향에 따라 선택 가능
(인터페이스 사용을 조금 더 추천)


─ 예시 ────────────────────────

type PlayerA = {
  // type은 interface와 다르게, 아예 값을 지정해줄 수 있음
  // ex) name: "Kang_Seong_il"
  name: string;
};

// type의 property 추가 방법(상속)
type PlayerAA = PlayerA & {
  lastName: string;
};

const playerA: PlayerAA = {
  name: "Seong_il",
  lastName: "Kang",
};

interface PlayerB {
  name: string;
}

// interface의 property 추가 방법(상속)
interface PlayerBB extends PlayerB {
  lastName: string;
}

// interface의 property 추가 방법 2(중복 추가)
interface PlayerB {
  health: number;
}

const playerB: PlayerBB = {
  name: "Seong_il",
  lastName: "Kang",
  health: 10,
};

console.log(playerA);
console.log(playerB);

https://www.typescriptlang.org/docs/handbook/2/
everyday-types.html#differences-between-type-aliases-and-interfaces

----------------------------------------------------------------------------

⚙️ typescript설치
npm i -D typescript

⚙️ package.json 초기화
npm init -y

⚙️ tsconfig.json설정
디렉터리에 tsconfig.json 파일이 있으면 해당 디렉터리가 TypeScript 프로젝트의 루트임을 나타냅니다.
tsconfig.json 파일은 프로젝트를 컴파일하는 데 필요한 루트 파일과 컴파일러 옵션을 지정합니다.
https://www.typescriptlang.org/docs/handbook/tsconfig-json.html#handbook-content

✅ Target (기본값: ES3)
최신 브라우저는 모든 ES6 기능을 지원하므로 ES6는 좋은 선택입니다. 코드가 이전 환경에 배포된 경우 더 낮은 
target을 설정하거나 최신 환경에서 코드 실행이 보장되는 경우 더 높은 target을 설정하도록 선택할 수 있습니다.
ex) 화살표 함수() => thisES5 이하이면 함수 표현식으로 바뀝니다.

특별한 ESNext 값은 TypeScript 버전이 지원하는 가장 높은 버전을 나타냅니다.
이 설정은 다른 TypeScript 버전 간에 동일한 의미가 아니며 업그레이드를 예측하기 어렵게 만들 수 있으므로 주의해서 사용해야 합니다.
https://www.typescriptlang.org/tsconfig#target

"build": "tsc" 또는 "npx tsc"

----------------------------------------------------------------------------

✅ lib

타입스크립트에게 어떤 API를 사용하고 어떤 환경에서 코드를 실행하는 지를 지정할 수 있습니다.
(target 런타임 환경이 무엇인지를 지정합니다.)
프로그램이 브라우저에서 실행되면 lib에 "DOM" 유형 정의를 할 수 있습니다.
DOM: window, document 등
ex) "lib": ["ES6","DOM"]

https://www.typescriptlang.org/tsconfig#lib

----------------------------------------------------------------------------

✅ strict

모든 엄격한 타입 검사 옵션을 활성화합니다.
strict 플래그는 프로그램 정확성을 더 강력하게 보장하는 광범위한 타입 검사 동작을 가능하게 합니다.

https://www.typescriptlang.org/tsconfig#strict

----------------------------------------------------------------------------

✅ @ts-check

JavaScript 파일에서 오류를 활성화하려면 // @ts-check를 .js 파일의 첫 번째 줄에 추가하여 TS가 오류를 발생시키도록 한다.
TypeScript는 여러 오류를 제공할 수 있습니다.
이러한 오류를 무시하고 싶다면 // @ts-ignore 또는 // @ts-expect-error를 추가하여 특정 줄의 오류를 무시할 수 있습니다.
https://www.typescriptlang.org/docs/handbook/intro-to-js-ts.html#ts-check

✅ JSDoc Reference

JSDoc 주석을 사용하여 JavaScript 파일에 type 정보를 제공할 수 있습니다. (자바스크립트 파일에서 타입 정보를 제공할 수 있다.)
https://www.typescriptlang.org/docs/handbook/jsdoc-supported-types.html

@param, @returns


─ 예시 ────────────────────────

/**
* @param {string} p1 - A string param.
* @param {string=} p2 - An optional param (Google Closure syntax)
* @param {string} [p3] - Another optional param (JSDoc syntax).
* @param {string} [p4="test"] - An optional param with a default value
* @returns {string} This is the result
*/
function stringsStringStrings(p1, p2, p3, p4) {
// 코드...
}

https://www.typescriptlang.org/docs/handbook/jsdoc-supported-types.html#param-and-returns

----------------------------------------------------------------------------

📌 DefinitelyTyped

TypeScript type 정의를 위한 리포지토리입니다.
https://github.com/DefinitelyTyped/DefinitelyTyped


─ 예시 ────────────────────────

@types/node
npm i @types/node -D

----------------------------------------------------------------------------

출처 - https://nomadcoders.co/typescript-for-beginners/lectures/3730 [LIMON029, sugar님]
profile
아이디어가 넘치는 프론트엔드를 꿈꿉니다 🔥

1개의 댓글

comment-user-thumbnail
2023년 7월 31일

좋은 정보 얻어갑니다, 감사합니다.

답글 달기