[Typescript] 타입스크립트 타입(2)

soob·2022년 7월 1일
0

typescript

목록 보기
2/2
post-thumbnail

리터럴 타입(Literal Types)

const userName1 = "Bob"; // 변경 불가함 
let userName2 = "Tom"; // 변경 가능

userName2 = 3; // error - string type으로 써야한다.

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

interface User {
	name: string;
    job: Job
}

const user: User = {
	name: string;
    job: "developer";
}

interface HignSchoolStudent {
	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(); // gift: Car
    } else {
    	gift.call(); // gift: Mobile
    }
}

교차 타입(Intersection Types)

모든 값을 적어줘야 한다.

interface Car {
	name: "car";
    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");

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

class Car {
	private name: string = "car"; // #name으로 써도 된다.
    protected name2: string;
    static wheels = 4;
    color: string;
    constructor(color: string) {
    	this.color = color;
    }
    start() {
    	console.log("start");
       console.log(this.name);
       console.log(Car.wheels); // 클래스 네임을 써줘서 접근해야한다.
    }
}

class Bmw extends Car {
	constructor(color: string) {
    	super(color);
    }
    showName() {
    	console.log(super.name); //error
    	console.log(super.name2); //가능
    }
}

const z4 = new Bmw("black");
console.log(z4.name2); // error
console.log(Car.wheels); 

public

자식 클래스나 클래스 인스턴스에서 접근이 가능하다. 아무것도 표기하지 않으면 모두 public.

private

해당 클래스 내부에서만 사용 가능하다.

protected

자식 클래스 내부에서는 참조할 수 있지만 클래스 인스턴스로는 접근이 불가능하다.

*수정할 수 없게 하려면 readonly로 써줘야 한다.

static

정적 멤버 변수는 this가 아니라 클래스명을 써서 접근해야한다.

추상 클래스

abstract class Car {
	color: string,
    constructor(color: string) {
    	this.color = color;
    }
    start() {
    	console.log("start");
    }
    abstract doSomething():void;
}

class Bmw extends Car {
	constructor(color: string) {
    	super(color);
    }
    doSomething() {
    	alert(3);
    }
}

추상 클래스는 new를 통해 객체를 만들 수 없다. 상속을 통해 가능.

제네릭

클래스나 함수 인터페이스를 다양한 타입으로 재사용 할 수 있다. 선언할 때는 타입 파라미터만 적어주고 생성하는 시점에 타입을 결정한다.

function getSize<T>(arr: T[]): number {
	return arr.length;
}

const arr1 = [1, 2, 3];
getSize<number | string>(arr1); // 3

const arr2 = ["a", "b", "c"];
getSize<string>(arr2); // 3 <string>을 써주지 않아도 타입을 구분한다.

const arr3 = [false, true, true];
getSize(arr3); // 3

const arr4 = [{}, {}, {name: "Tim"}];
getSize(arr4); // 3
//interface 사용
interface Mobile<T> {
	name: string;
    price: number;
    option: T;
}

const m1:Mobile<{color: string; coupon: boolean}> = {
	name: "s21",
    price: 1000,
    option: {
    	color: "red",
        coupon: false,
    }
}

const m2:Mobile<string> = {
	name: "s20",
    price: 900,
    option: "good"
}
interface User {
	name: string;
    age: number;
}

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

interface Book {
	price: number;
}

const user: User = {name: "a", age: 10};
const car: Car = {name: "bmw", color: "red"};
const book: Book = {price: 3000};

function showName<T extends {name: string}>(data: T):string {
	return data.name;
}

showName(user);
showName(car);
//showName(book); error

유틸리티 타입

keyof

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

type UserKey = keyof User; // 키 값을 유니온 형태로 받을 수 있다. "id" | "name" | "age" | "gender"

const uk:UserKey = "id";

Partial<T>

프로퍼티를 모두 옵셔널로 바꿔준다.

interface User {
	id: number;
    name: string;
    age: number;
    gender: "m" | "f";
}
/*
	interface User {
    	id?: number;
        name?:string;
        age?: number;
        gender ?: "m" | "f"
    }
*/
let admin: Partial<User> = {
	id: 1,
    name: "Bob"
}

Required<T>

모든 프로퍼티를 필수로 바꿔준다.

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

let admin: Required<User> = {
	id: 1,
  	name: "Bob"
    //age 없어서 에러발생
}

Readonly<T>

읽기 전용으로 바꿔준다. 처음 할당만 가능하고 수정 불가.

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

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

admin.id = 4; // 에러발생

Record<K, T>

프로퍼티 키 값을 K 타입으로, 값을 T 타입으로 하는 타입을 만들 수 있다.

/*
interface Score {
	"1": "A" | "B" | "C" | "D";
	"2": "A" | "B" | "C" | "D";
	"3": "A" | "B" | "C" | "D";
	"4": "A" | "B" | "C" | "D";
}
*/
type Grade = "1" | "2" | "3" | "4";
type Score = "A" | "B" | "C" | "D";

const score:Record<Grade, Score> = {
	1: "A",
    2: "C",
    3: "B",
    4: "D",
}

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

function isValid(user: User) {
	const result: Record<keyof User, boolean> = {
    	id: user.id > 0,
        name: user.name !== "",
      	age: user.age > 0,
    }
    return result;
}

Pick<T, K>

k 프로퍼티만 골라서 사용.

interface User {
	id: number;
    name: string;
    age: number;
    gender: "M" | "W";
}

const admin: Pick<User, "id" | "name"> = {
	id: 0,
    name: "Bob"
}
//id와 name 가져와서 사용

Omit<T, K>

k 프로퍼티만 생략하고 사용.

interface User {
	id: number;
    name: string;
    age: number;
    gender: "M" | "W"
}

const admin: Omit<User, "age" | "gender"> = {
	id: 0,
  	name: "Bob"
}
// age, gender를 제외하고 사용한다.

Exclude<T1, T2>

T1에서 T2랑 겹치는 타입을 제거

type T1 = string | number | boolean;
type T2 = Exclude<T1, number | string>;
//number와 string 제거

NonNullable<Type>

null/undefined 를 제외

type T1 = string | null | undefined | void;
type T2 = NonNullable<T1>;

0개의 댓글