typescript 기억할만한 것.

JEON.HYEONG.JUN·2022년 7월 22일
0

유튜브 '코딩앙마'님의 TS강의를 보며 잊어버릴 것같은 것들만 정리해보자.

📌타입스크립트의 기본타입

//배열을 선언할 시 가능한 두가지 방법
let a:number[] = [1,2,3];
let a:Array<number> = [1,2,3];
//튜플
let b: [string, nuumber];
b = ['z', 1];
//b = [1, 'z']; // 순서도 엄격히 맞춰줘야 한다.
//함수가 아무것도 반환하지 않을 때 사용하는 void.
function saYhello():void{
	console.log('HELLO!');
}
//never
function showError():never{
	throw new Error();
} // 에러를 반환하거나,

function infLoop():never{
	while(true) {
       //do something..  
    }
} //영원히 끝나지않는 함수.
//enum
enum Os {
	window,
  	Ios,
  	Android
}

enum에 값을 할당하지 않으면, 자동으로 0부터 할당된다.

//enum
enum Os {
	window = 3, // 그 다음 값들은 4, 5가 된다.
  	Ios, //10을 할당한다면 다음 값은 11이 된다.
  	Android
}

이렇게 양방향으로 인식된다.

이런식으로 사용할 수 있다.

문자열도 할당할 수 있으며, 이 때는 단방향으로 인식된다.
컴파일 시에 const Os = {}의 형식으로 컴파일된다!

enum Os {
    Window = 'win',
    Ios = 'ios',
    Android = 'and'
}

let myOs:Os; //Os에 있는 값들만 사용가능하다.

이런 식으로 사용가능.

특정값만 입력할 수 있도록 강조하고 싶을 때, 그리고 그 값들이 공통점이 있을 때 enum을 사용한다.


📌 인터페이스

let user:object;

user = {
name: 'xx',
age: 30
}

이런식으로 덜렁 object만 써주면 에러발생한다.
프로퍼티를 정의해서 객체로 사용하고자 할때는 인터페이스를 사용한다.


interface 내부에 gender추가해도 소용없다.
user객체 내부에 gender가 사용되지않고 있기 때문.
?를 사용한다.

//readonly와 grade부분을 보자.
interface User {
    name : string;
    age : number;
    gender?: string; 
    readonly birthYear : number;
  	[grade:number] : string; // 키를 number로, 값을 string으로 받을 수 있는 프로퍼티를 여러개 추가할 수 있다. 
}

let user : User = {
    name: 'xx',
    age: 30,
    birthYear : 2000,
  	1 : 'A',
  	2 : 'B'
}

user.age = 10; //
user.gender = 'male';
user.birthYear = 1999; //readonly로 선언됐기 때문에 할당 후 수정불가.

grade부분은 더 좋은 방법이 있다.

type score = 'A' | 'B' | 'C' | 'F';

interface User {
    name : string;
    age : number;
    gender?: string;
    readonly birthYear : number;
    [grade:number] : score; //type에서 지정한 값들 이외에는 올 수가 없다!
}

let user : User = {
    name: 'xx',
    age: 30,
    birthYear : 2000,
    1 : 'A',
    2 : 'B'
}

interface의 사용예를 더 보고 가자.


interface로 class를 지정해보자.

확장(extends)을 사용해보자.

//확장 시 여러 인터페이스를 동시에 적용 가능.
interface Car {
    color: string;
    wheels: number;
    start(): void;
} 

interface Toy {
    name: string;
}

interface ToyCar extends Car, Toy {
    price : number;
}

📌 함수

선택적 매개변수를 앞에서 사용하면 안된다.

굳이 사용하고 싶다면

이렇게 명시적으로 사용해야 한다.


//나머지 매개변수에 대한 형식지정.
function add(...nums: number[]) {
    return nums.reduce((result, num) => result + num, 0);
}

add(1, 2, 3)


  • 함수 오버로딩
    동일한 함수지만 매개변수의 타입이나 개수에 따라 다른 방식으로 동작해야한다면 오버로드를 사용할 수 있다.


📌 리터럴, 유니온/교차 타입

//literal

const userName1 = 'Bob';
let userName2: string | number = 'Tom';
userName2 = 3;

type Job = 'police' | 'developer' | 'teacher';

interface User {
    name : string;
    job : Job;
}

const user: User = {
    name: 'Bob',
    job: 'developer',
};

interface HighSchoolStudent {
    name: number | string;
    grade: 1 | 2 | 3;
}

//Union types

interface Car {
    name: 'car';
    color: string;
    start(): void;
}

interface Mobile {
    name: 'mobile';
    color: string;
    call(): void;
}

function getGift(gift: Car | Mobile) {
    console.log(gift.color);
    if(gift.name === 'car'){
    gift.start(); // Car에만 start()가 있기 때문.
    } else {
        gift.call();
    }

}

//Intersection Types

interface Car {
    name: string;
    start(): void;
}

interface Toy {
    name: string;
    color: string;
    price: number;
}

const toyCar: Toy & Car = { //모든 프로퍼티를 사용해야 한다.
    name: '타요',
    start() {},
    color: 'blue',  
    price: 1000,
}

📌 클래스

class Car {
    color: string;
    constructor(color: string){
        this.color = color;
    }
    start() {
        console.log('start');
    }
}

const bmw = new Car('red');
//멤버변수를 사용하지 않는 방법.
class Car {
    //color: string; 
    constructor(public color: string){ //public 또는 readonly도 가능!
        this.color = color;
    }
    start() {
        console.log('start');
    }
}

const bmw = new Car('red');

//접근 제한자(Access modifier) - public, private, protected

class Car {
    name: string = 'Car';
    color: string;
    constructor(color: string){
        this.color = color;
    }
    start() {
        console.log('start');
    }
}

class Bmw extends Car {
    constructor(color: string) {
        super(color);
    }
    showName() {
        console.log(super.name);
    }
}

const z4 = new Bmw('black');


위의 스샷에서 헷갈릴까봐 적어두는데 첫번째 주석에서 public이 아니라 private일때만 Car안에서만 접근가능이라는 뜻이다.
그리고 public은 생략하고 사용 가능이다.



protected는 자식클래스에는 존재할 수 있으나 인스턴스로는 존재할 수없다!


public - 자식클래스, 클래스 인스턴스 모두 접근 가능
protected - 자식 클래스에서만 접근 가능
private - 해당 클래스 내부에서만 접근 가능


class 내 객체 생성시마다 함께 생성되는 멤버 변수(메서드 밖에서 선언된 변수)를
static 화 하여 생성시마다 생기는 메모리 누수를 막아보자



📌 제네릭




📌 유틸리티 타입

// keyof

interface User {
    id: number;
    name: string;
    age: number;
    gender: 'm' | 'f';
}

type UserKey = keyof User; // 'id' | 'name' | 'age' | 'gender'

const uk:UserKey = 'id' // User 인터페이스의 키값을 입력하면 된다.

// Partial<T>

interface User {
    id: number;
    name: string;
    age: number;
    gender: 'm' | 'f';
}

let admin: Partial<User> = { //partial의 사용방법.
    id: 1,
    name: 'Bob',
}


// interface User {.          //Partial을 쓰면 이것과 같은 형태이다.
//     id?: number;
//     name?: string;
//     age?: number;
//     gender?: 'm' | 'f';
// }

// Required<T>

interface User {
    id: number;
    name: string;
    age?: number;
}

let admin: Required<User> = { //age가 필수 프로퍼티가 되어버렸다. 안넣으면 에러.
    id: 1,
    name: 'Bob',
    age: 30,
}

// Readonly<T>

interface User {
    id: number;
    name: string;
    age?: number;
}

let admin: Readonly<User> = {
    id: 1,
    name: 'Bob',
}

admin.id = 4; //Readonly로 감싸준다면 값 못바꾼다. (원래 가능.)

// Record<K,T> 예제 1.

// interface Score {
//     '1': 'A' | 'B' | 'C' | 'D';
//     '2': 'A' | 'B' | 'C' | 'D';
//     '3': 'A' | 'B' | 'C' | 'D';
//     '4': 'A' | 'B' | 'C' | 'D';
// }
const score: Record<'1'|'2'|'3'|'4', 'A' | 'B' | 'C' | 'D'> = { //Record<key, value>
    1: 'A',
    2: 'C',
    3: 'B',
    4: 'D',
}
type Grade = '1'|'2'|'3'|'4';
type Score = 'A' | 'B' | 'C' | 'D';  //type으로 저장 후 사용 가능.
const score: Record<Grade, Score> = { 
    1: 'A',
    2: 'C',
    3: 'B',
    4: 'D',
}

// Record<K,T> 예제 2.

interface User {
    id: number;
    name: string;
    age: number;
}

function isValid(user:User){
    const result: Record<keyof User, boolean> = { //keyof를 활용하여 키값을 입력했다.
        id: user.id > 0,
        name : user.name !== '',
        age : user.age > 0
    }
    return result;
}

// Pick<T, K>

interface User {
    id: number;
    name: string;
    age: number;
    gender: 'M' | 'F';
}

const admin: Pick<User, 'id' | 'name'> = { //id와 name만 가지고 왔다.
    id: 0,
    name: 'Bob',
}

// Omit<T,K>

interface User {
    id: number;
    name: string;
    age: number;
    gender: 'M' | 'F';
}

const admin: Omit<User, 'age' | 'gender'> = { // 특정 프로퍼티 값 제외.
    id: 0,
    name: 'Bob',
}

// Exclude<T1, T2>

type T1 = string | number | boolean;
type T2 = Exclude<T1, number | string>; //boolean만 남는다.

// NonNullable<Type>

//null과 undefined를 제외한다.
type T1 = string | null | undefined | void;
type T2 = NonNullable<T1> // string과 void만 남는다.
profile
💻😀👍🎁👏😁

0개의 댓글