Jieunny์˜ ๋ธ”๋กœ๊ทธ

[TS] 2. Usage ๋ณธ๋ฌธ

Study/TypeScript

[TS] 2. Usage

Jieunny 2023. 1. 27. 15:35

๐Ÿ“ฃ  Module

โœ”๏ธ ๋ชจ๋“ˆ์€ ์ „์—ญ ๋ณ€์ˆ˜๊ณผ ๊ตฌ๋ถ„๋˜๋Š” ์ž์ฒด ์œ ํšจ ๋ฒ”์œ„๋ฅผ ๊ฐ€์ง€๋ฉฐ export, import์™€ ๊ฐ™์€ ํ‚ค์›Œ๋“œ ์—†์ด๋Š” ๋‹ค๋ฅธ ํŒŒ์ผ์—์„œ ์ ‘๊ทผํ•  ์ˆ˜ ์—†๋‹ค.

 

๐Ÿ“ฃ  Export, Import

โœ”๏ธ ES6์˜ export์™€ ๊ฐ™์€ ๋ฐฉ์‹์œผ๋กœ ๋ณ€์ˆ˜, ํ•จ์ˆ˜, ํƒ€์ž…, ์ธํ„ฐํŽ˜์ด์Šค ๋“ฑ์— ๋ถ™์—ฌ ์‚ฌ์šฉํ•œ๋‹ค.

โž• JS ES6 ๋ฌธ๋ฒ•

๋”๋ณด๊ธฐ

โžฐ 2015๋…„์— ์ถœ์‹œ๋œ ECMAScript, ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ์˜ ํ‘œ์ค€

โžฐ let, const ํ‚ค์›Œ๋“œ ์ถ”๊ฐ€

โžฐ ํ…œํ”Œ๋ฆฟ ๋ฆฌํ„ฐ๋Ÿด, ๊ฐ์ฒด ๋ฆฌํ„ฐ๋Ÿด, ํ™”์‚ดํ‘œ ํ•จ์ˆ˜ ๋“ฑ์ด ์ถ”๊ฐ€ ๋œ ๋ฌธ๋ฒ•

// math.ts
export interface Triangle {
	width: number;
    height: number;
}

// index.ts
import { Triangle } from './math.ts';

class SomeTriangle implements Triangle {
	//...
}
import { WheatBeerClass } from './index.ts';

class Cloud extends WheatBeerClass {
}

โž• Extends VS Implements

๋”๋ณด๊ธฐ

โœ”๏ธ Extends

โžฐ ์ƒ์†๋ฐ›๊ณ ์ž ํ•˜๋Š” ๋ถ€๋ชจ ํด๋ž˜์Šค๋ฅผ ๋ช…์‹œํ•˜๋Š” ๊ฒƒ

โžฐ ํ•ด๋‹น ํด๋ž˜์Šค์˜ ํ”„๋กœํผํ‹ฐ์™€ ๋ฉ”์„œ๋“œ๋ฅผ ๋”ฐ๋กœ ๊ตฌํ˜„ํ•˜๊ธฐ ์•Š์•„๋„ ์ธ์Šคํ„ด์Šค์—์„œ ์ž์œ ๋กญ๊ฒŒ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.

โžฐ '๋ถ€๋ชจ ๊บผ ๋ง˜๋Œ€๋กœ ๊ฐ–๋‹ค ์“ธ ์ˆ˜ ์žˆ์Œ'

 

โœ”๏ธ Extends

โžฐ ๋ฏธ๋ฆฌ ์ถ”์ƒํ™” ๋œ ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ์ฑ„ํƒํ•˜์—ฌ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ

โžฐ ์ƒ์†๊ณผ ๋‹ค๋ฅด๊ฒŒ ์–ด๋–ค ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ์ฑ„ํƒํ•˜๋ฉด ์ถ”์ƒํ™” ๋œ ๋ฉ”์„œ๋“œ๋‚˜ ํ”„๋กœํผํ‹ฐ๋ฅผ ๋ฐ˜๋“œ์‹œ ๊ตฌํ˜„ํ•ด์•ผ ํ•œ๋‹ค.

โžฐ 'ํ•ด๋‹น ํด๋ž˜์Šค๋Š” ์ด ์ธํ„ฐํŽ˜์ด์Šค ๋ชจ์–‘์ด๋‹ˆ๊นŒ ๋ฐ˜๋“œ์‹œ ์ด ์กฐ๊ฑด์„ ๊ฐ€์ ธ์•ผ ํ•ด'

 

๐Ÿ“ฃ  TS๋Š” ๋ชจ๋“ˆ ์ฝ”๋“œ๋ฅผ ์–ด๋–ป๊ฒŒ ๋ณ€ํ™˜ํ• ๊นŒ?

โœ”๏ธ tsconfig.json ํŒŒ์ผ์— ์„ค์ •ํ•œ ์ปดํŒŒ์ผ๋Ÿฌ ๋ชจ๋“œ์— ๋”ฐ๋ผ ๋ชจ๋“ˆ ์ฝ”๋“œ๊ฐ€ ๊ฐ๊ธฐ ๋‹ค๋ฅด๊ฒŒ ๋ณ€ํ™˜๋œ๋‹ค.

# commonjs ๋ชจ๋“œ์ธ ๊ฒฝ์šฐ
tsc --module commonjs Test.ts

# amd ๋ชจ๋“œ์ธ ๊ฒฝ์šฐ
tsc --module amd Test.ts

๐Ÿ“ฃ d.ts ํŒŒ์ผ

โœ”๏ธ ํƒ€์ž…์Šคํฌ๋ฆฝํŠธ ์„ ์–ธ ํŒŒ์ผ๋กœ, ์ฝ”๋“œ์˜ ํƒ€์ž… ์ถ”๋ก ์„ ๋•๋Š” ํŒŒ์ผ

โœ”๏ธ ๊ธฐ์กด JS๋กœ ๋งŒ๋“ค์–ด์ง„ ์จ๋“œํŒŒํ‹ฐ ๋ชจ๋“ˆ๋“ค์„ TSํ™˜๊ฒฝ์—์„œ๋„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋„๋ก ๋”ฐ๋กœ ํƒ€์ž…๋งŒ ์ •๋ฆฌํ•ด์„œ ๋„ฃ์–ด๋‘” ํŒŒ์ผ

declare const global = "sth";

โžฐ ์ „์—ญ ๋ณ€์ˆ˜๋กœ ์„ ์–ธํ•œ ๋ณ€์ˆ˜๋ฅผ ํŠน์ • ํŒŒ์ผ์—์„œ import ๊ตฌ๋ฌธ ์—†์ด ์‚ฌ์šฉํ•˜๋Š” ๊ฒฝ์šฐ ํ•ด๋‹น ๋ณ€์ˆ˜๋ฅผ ์ธ์‹ํ•˜์ง€ ๋ชปํ•œ๋‹ค.

โžฐ ๊ทธ๋Ÿด ๋•Œ, ์œ„์ฒ˜๋Ÿผ ํ•ด๋‹น ๋ณ€์ˆ˜๋ฅผ ์„ ์–ธํ•ด์„œ ์—๋Ÿฌ๊ฐ€ ๋‚˜์ง€ ์•Š๊ฒŒ ํ•  ์ˆ˜ ์žˆ๋‹ค.

 

โœ”๏ธ ์ „์—ญ ๋ณ€์ˆ˜์™€ ์ „์—ญ ํ•จ์ˆ˜์— ๋Œ€ํ•œ ํƒ€์ž… ์„ ์–ธ

โžฐ ํ•ด๋‹น ํƒ€์ž…์Šคํฌ๋ฆฝํŠธ ํŒŒ์ผ์—์„œ ์‚ฌ์šฉํ•  ์ˆœ ์žˆ์ง€๋งŒ ์„ ์–ธ๋˜์–ด ์žˆ์ง€ ์•Š์€ ์ „์—ญ ๋ณ€์ˆ˜๋‚˜ ์ „์—ญ ํ•จ์ˆ˜๋Š” ํƒ€์ž…์„ ์„ ์–ธํ•  ์ˆ˜ ์žˆ๋‹ค.

// ์ „์—ญ ๋ณ€์ˆ˜
declare const pi = 3.14;

// ์ „์—ญ ํ•จ์ˆ˜
declare namespace myLib {
	function greet(person: string): string;
    let name: string;
}
myLib.greet('์บกํ‹ด');
myLib.name = 'ํƒ€๋…ธ์Šค';

 

โž• declare & declare namespace 

๋”๋ณด๊ธฐ

โœ”๏ธ declare 

โžฐ ํƒ€์ž…์Šคํฌ๋ฆฝํŠธ ์ปดํŒŒ์ผ๋Ÿฌ์—๊ฒŒ ํŠน์ •ํ•œ ๋ณ€์ˆ˜๊ฐ€ ์žˆ๋‹ค๊ณ  ์„ ์–ธํ•˜๋Š” ํ‚ค์›Œ๋“œ

โžฐ ๋‚ด๊ฐ€ ๋งŒ๋“  ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์˜ ํƒ€์ž… ์ •๋ณด๋ฅผ ์™ธ๋ถ€ ์‚ฌ์šฉ์ž์—๊ฒŒ ์•Œ๋ ค์ค„ ๋ชฉ์ ์œผ๋กœ d.ts ํŒŒ์ผ์„ ์ •์˜ํ•  ๋•Œ ์‚ฌ์šฉํ•œ๋‹ค.

 

โœ”๏ธ declare namespace

โžฐ ์ปดํŒŒ์ผ๋Ÿฌ๋Š” namespace๋กœ ์„ ์–ธํ•œ TS ์ฝ”๋“œ๋ฅผ JS ์ผ๋ฐ˜ ๊ฐ์ฒด๋กœ ์ปดํŒŒ์ผ ํ•˜๋Š”๋ฐ, declare ํ‚ค์›Œ๋“œ๋ฅผ ๋ถ™์—ฌ์ฃผ๋ฉด JS ์ฝ”๋“œ๋กœ ์ปดํŒŒ์ผ์„ ํ•˜์ง€ ์•Š๋Š”๋‹ค.

โžฐ ๊ฐ์ฒด์˜ ํƒ€์ž… ์ •๋ณด๋งŒ ์•Œ๋ ค์ฃผ๋Š” ์—ญํ• ์„ ํ•˜๊ฒŒ ๋œ๋‹ค.


๐Ÿ“ฃ  ์ธ๋ฑ์‹ฑ

โœ”๏ธ ๋ฐฐ์—ด ์š”์†Œ ์ ‘๊ทผ

interface StringArray {
	[index: number]: string;
}

const arr: StringArray = ['Thor', 'Hulk'];
arr[0];	// 'Thor'

โžฐ ํƒ€์ž…์Šคํฌ๋ฆฝํŠธ์—์„œ๋Š” ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ์ด์šฉํ•ด์„œ ์ธ๋ฑ์‹ฑ ํƒ€์ž…์„ ์ •์˜ํ•  ์ˆ˜ ์žˆ๋‹ค.

โžฐ ๋ฐฐ์—ด์˜ ์ธ๋ฑ์Šค์˜ ํƒ€์ž…์€ ์ˆซ์ž, ์ด ์ธ๋ฑ์Šค๋กœ ํŠน์ • ์š”์†Œ๋ฅผ ์ ‘๊ทผํ–ˆ์„ ๋•Œ ํ•ด๋‹น ์š”์†Œ์˜ ํƒ€์ž…์€ string ์ด๋ผ๋Š” ๊ฒƒ์„ ๋ช…์‹œํ–ˆ๋‹ค.

 

โœ”๏ธ ํƒ€์ž…์œผ๋กœ ๋ฐฐ์—ด ๋ณ€๊ฒฝ ์ œํ•œํ•˜๊ธฐ

interface ReadonlyStringArray {
	readonly [index: number]: string;
}

const arr: ReadonlyStringArray = ['Thor', 'Hulk'];
arr[2] = 'Capt';	//์—๋Ÿฌ!

โžฐ ๋ฐฐ์—ด์˜ ์š”์†Œ๋ฅผ ๋ณ€๊ฒฝํ•˜์ง€ ๋ชปํ•˜๊ฒŒ ํ•˜๋ ค๋ฉด readonly๋ฅผ ๋ถ™์—ฌ์ฃผ์–ด์•ผ ํ•œ๋‹ค.


๐Ÿ“ฃ  ์œ ํ‹ธ๋ฆฌํ‹ฐ ํƒ€์ž…

โœ”๏ธ ์ด๋ฏธ ์ •์˜ํ•ด ๋†“์€ ํƒ€์ž…์„ ๋ณ€ํ™˜ํ•  ๋•Œ ์‚ฌ์šฉํ•˜๊ธฐ ์ข‹์€ ํƒ€์ž… ๋ฌธ๋ฒ•

โœ”๏ธ ์œ ํ‹ธ๋ฆฌํ‹ฐ ํƒ€์ž…์„ ์“ฐ์ง€ ์•Š์•„๋„ ๊ธฐ์กด ๋ฌธ๋ฒ•์œผ๋กœ ํƒ€์ž…์„ ๋ณ€ํ™”ํ•  ์ˆ˜ ์žˆ์ง€๋งŒ, ์œ ํ‹ธ๋ฆฌํ‹ฐ ํƒ€์ž…์„ ์“ฐ๋ฉด ํ›จ์”ฌ ๋” ๊ฐ„๊ฒฐํ•˜๊ฒŒ ๊ฐ€๋Šฅํ•˜๋‹ค.

 

๐Ÿ“ฃ  ์ž์ฃผ ์‚ฌ์šฉ๋˜๋Š” ์œ ํ‹ธ๋ฆฌํ‹ฐ ํƒ€์ž…

1๏ธโƒฃ Partial<Type>

โžฐ ํŠน์ • ํƒ€์ž…์˜ ๋ถ€๋ถ„ ์ง‘ํ•ฉ์„ ๋งŒ์กฑํ•˜๋Š” ํƒ€์ž…์„ ์ •์˜ํ•  ์ˆ˜ ์žˆ๋‹ค.

interface Address {
    email: string;
    address: string;
}

type MayHaveEmail = Partial<Address>;
const me: MayHaveEmail = {};	//๊ฐ€๋Šฅ
const you: MayHaveEmail = { email: 'test@abc.com' };	//๊ฐ€๋Šฅ
const all: MayHaveEmail = { email: 'capt@hero.com', address: 'Pangyo' }; //๊ฐ€๋Šฅ

โžฐ  ์•„๋ฌด ์†์„ฑ์„ ๊ฐ€์ง€์ง€ ์•Š๊ฑฐ๋‚˜, ํ•˜๋‚˜๋งŒ ๊ฐ€์ง€๊ฑฐ๋‚˜, ๋ชจ๋‘ ๊ฐ€์ง€๋Š” ํƒ€์ž…์„ ์ •์˜ํ•  ์ˆ˜ ์žˆ๋‹ค.

 

2๏ธโƒฃ Pick<Type, Keys>

โžฐ ํŠน์ • ํƒ€์ž…์—์„œ ๋ช‡ ๊ฐœ์˜ ์†์„ฑ์„ ์„ ํƒํ•˜์—ฌ ํƒ€์ž…์„ ์ •์˜ํ•  ์ˆ˜ ์žˆ๋‹ค.

โžฐ Type์—์„œ keys์˜ ์ง‘ํ•ฉ์„ ์„ ํƒํ•ด ํƒ€์ž…์„ ์ƒ์„ฑ

interface Hero {
    name: string;
    skill: string;
}
const human: Pick<Hero, 'name'> = {
	name: '์Šคํ‚ฌ์ด ์—†๋Š” ์‚ฌ๋žŒ',
};

โžฐ name ์†์„ฑ๋งŒ ์„ ํƒํ•ด์„œ ์ •์˜ ๊ฐ€๋Šฅ

 

type HasThen<T> = Pick<Promise<T>, 'then' | 'catch'>;
let hasThen: HasThen<Number> = Promise.resolve(4);
hasThen.then	//์œ„์—์„œ 'then'๋งŒ ์„ ํƒํ•˜๋ฉด 'then'๋งŒ ์ œ๊ณต, 'catch' ์„ ํƒํ•˜๋ฉด 'catch'๋งŒ ์ œ๊ณต

โžฐ ํƒ€์ž…์Šคํฌ๋ฆฝํŠธ์—์„œ Promise๋Š” ์œ„์ฒ˜๋Ÿผ ์ œ๋„ค๋ฆญ ํด๋ž˜์Šค ํ˜•ํƒœ๋กœ ์‚ฌ์šฉํ•œ๋‹ค.

 

3๏ธโƒฃ Omit<Type, Keys>

โžฐ ํŠน์ • ํƒ€์ž…์—์„œ ์ง€์ •๋œ ์†์„ฑ๋งŒ ์ œ๊ฑฐํ•œ ํƒ€์ž…์„ ์ •์˜ํ•ด ์ค€๋‹ค.

โžฐ Type์—์„œ ๋ชจ๋“  ํ”„๋กœํผํ‹ฐ๋ฅผ ์„ ํƒํ•˜๊ณ  keys๋ฅผ ์ œ๊ฑฐํ•œ ํƒ€์ž…์„ ์ƒ์„ฑ 

interface AddressBook {
    name: string;
    phone: number;
    address: string;
    company: string;
}
const phoneBook: Omit<AddressBook, 'address'> = {
    name: '์žฌํƒ๊ทผ๋ฌด',
    phone: 123422223333,
    company: '๋‚ด ๋ฐฉ'
}
const chingtao: Omit<AddressBook, 'address'|'company'> = {
    name: '์ค‘๊ตญ์ง‘',
    phone: 44455556666
}

๐Ÿ“ฃ  ๋งต๋“œ ํƒ€์ž…(Mapped Type)

โœ”๏ธ ๊ธฐ์กด์— ์ •์˜๋˜์–ด ์žˆ๋Š” ํƒ€์ž…์„ ์ƒˆ๋กœ์šด ํƒ€์ž…์œผ๋กœ ๋ณ€ํ™˜ํ•ด ์ฃผ๋Š” ๋ฌธ๋ฒ•์„ ์˜๋ฏธํ•œ๋‹ค.

โœ”๏ธ ๋งˆ์น˜ JS์˜ map() API ํ•จ์ˆ˜๋ฅผ ํƒ€์ž…์— ์ ์šฉํ•œ ๊ฒƒ๊ณผ ๊ฐ™์€ ํšจ๊ณผ๋ฅผ ๊ฐ€์ง„๋‹ค.

โœ”๏ธ ๋งต๋“œ ํƒ€์ž…์˜ ๊ธฐ๋ณธ ๋ฌธ๋ฒ•

โžฐ ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ์˜ map ํ•จ์ˆ˜๋ฅผ ํƒ€์ž…์— ์ ์šฉํ–ˆ๋‹ค๊ณ  ๋ณด๋ฉด ๋œ๋‹ค.

{ [ P in K ] : T }
{ [ P in K ] ? : T }
{ readonly [ P in K ] : T }
{ readonly [ P in K ] ? : T }

 

โœ”๏ธ ๋งต๋“œ ํƒ€์ž…์˜ ๊ธฐ๋ณธ ์˜ˆ์ œ

type Heroes = 'Hulk' | 'Thor' | 'Capt';

โžฐ ํ—ํฌ, ํ† ๋ฅด, ์บกํ‹ด์„ ์œ ๋‹ˆ์˜จ ํƒ€์ž…์œผ๋กœ ๋ฌถ์–ด์ฃผ๋Š” Heroes ํƒ€์ž…

โžฐ ์„ธ ์˜์›…์˜ ์ด๋ฆ„์— ๊ฐ๊ฐ ๋‚˜์ด๊นŒ์ง€ ๋ถ™์ธ ๊ฐ์ฒด๋ฅผ ๋งŒ๋“ค๊ณ  ์‹ถ๋‹ค๋ฉด?

type HeroProfiles = { [K in Heroes]: number );
const heroInfo: HeroProfiles = {
    Hulk: 54,
    Thor: 1000,
    Capt: 33,
}

โžฐ Heroes ํƒ€์ž…์˜ 3๊ฐœ์˜ ๋ฌธ์ž์—ด์„ ๊ฐ๊ฐ ์ˆœํšŒํ•˜์—ฌ number ํƒ€์ž…์„ ๊ฐ’์œผ๋กœ ๊ฐ€์ง€๋Š” ๊ฐ์ฒด์˜ ํ‚ค๋กœ ์ •์˜๊ฐ€ ๋œ๋‹ค.

type HeroProfiles = {
    Hulk: number;
    Thor: number;
    Capt: number;
}

 

โœ”๏ธ ๋งต๋“œ ํƒ€์ž…์˜ ์‹ค์šฉ ์˜ˆ์ œ1

type Subset<T> = {
    [K in keyof T]? : T[K];
}

โžฐ ํ‚ค์™€ ๊ฐ’์ด ์žˆ๋Š” ๊ฐ์ฒด๋ฅผ ์ •์˜ํ•˜๋Š” ํƒ€์ž…์„ ๋ฐ›์•„ ๊ทธ ๊ฐ์ฒด์˜ ๋ถ€๋ถ„ ์ง‘ํ•ฉ์„ ๋งŒ์กฑํ•˜๋Š” ํƒ€์ž…์œผ๋กœ ๋ณ€ํ™˜ํ•ด์ฃผ๋Š” ๋ฌธ๋ฒ•

interface Person {
    age: number;
    name: string;
}

const ageOnly: Subset<Person> = { age: 23 };
const nameOnly: Subset<Person> = { name: 'Tony' };
const ironman: Subset<Person> = { age: 23, name: 'Tony' };
const empty: Subset<Person> = {};

 

โœ”๏ธ ๋งต๋“œ ํƒ€์ž…์˜ ์‹ค์šฉ ์˜ˆ์ œ2

โžฐ ์‚ฌ์šฉ์ž ํ”„๋กœํ•„์„ ์กฐํšŒํ•˜๋Š” API ํ•จ์ˆ˜

interface UserProfile {
    username: string;
    email: string;
    profilePhotoUrl: string;
}

function fetchUserProfile(): UserProfile {
	//...
}

 

 

โžฐ ํ”„๋กœํ•„์˜ ์ •๋ณด๋ฅผ ์ˆ˜์ •ํ•˜๋Š” API

type UserProfileUpdate = {
    [p in keyof UserProfile]?: UserProfile[p]
}