Skip to Content
Sunbeen's Blog
Documents๊ตฌ TypescriptBasic_Grammer12. ๐ŸŸฆ TypeScript - ์˜ต์…”๋„(Optional) & ์ œ๋„ค๋ฆญ(Generic) ์ •๋ฆฌ

12. ๐ŸŸฆ TypeScript - ์˜ต์…”๋„(Optional) & ์ œ๋„ค๋ฆญ(Generic) ์ •๋ฆฌ

๐Ÿ“Œ 1. ์˜ต์…”๋„(Optional)

โœ… ์‚ฌ์šฉ ๋ฐฉ๋ฒ•

  • ?๋Š” ํ•ญ์ƒ ์†์„ฑ๋ช… ๋˜๋Š” ๋งค๊ฐœ๋ณ€์ˆ˜ ์ด๋ฆ„ ๋’ค์— ๋ถ™์ž…๋‹ˆ๋‹ค.
  • ์กด์žฌํ•ด๋„ ๋˜๊ณ , ์—†์–ด๋„ ๋˜๋Š” ๊ฐ’์„ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค.

โœ… ํ•จ์ˆ˜ ๋งค๊ฐœ๋ณ€์ˆ˜์—์„œ ์˜ต์…”๋„ ์‚ฌ์šฉ

function abc(a: number, b?: number, c?: number) {} abc(1); // ์ „๋ถ€ ๊ฐ€๋Šฅํ•˜๋‹ค abc(1, 2); // ์ „๋ถ€ ๊ฐ€๋Šฅํ•˜๋‹ค abc(1, 2, 3); // ์ „๋ถ€ ๊ฐ€๋Šฅํ•˜๋‹ค

โ— ์ฃผ์˜: ์˜ต์…”๋„ ๋งค๊ฐœ๋ณ€์ˆ˜๋Š” ๋งˆ์ง€๋ง‰์— ๋ฐฐ์น˜ํ•˜๋Š” ๊ฒƒ์ด ์ข‹์Šต๋‹ˆ๋‹ค.

โœ… ๋‚˜๋จธ์ง€ ๋งค๊ฐœ๋ณ€์ˆ˜(rest parameter)

// ์ œํ•œ์—†์ด ์ž…๋ ฅ์„ ๋ฐ›๊ณ  ์‹ถ์€ ๊ฒฝ์šฐ function abc(...args: number[]) {} abc(1, 2, 3, 4);

โœ… type alias์—์„œ ์˜ต์…”๋„

// type alias์—์„œ ์˜ต์…”๋„ ์‚ฌ์šฉ type User = { id: number; nickname?: string; // ์žˆ์–ด๋„ ๋˜๊ณ  ์—†์–ด๋„ ๋จ }; const u1: User = { id: 1 }; const u2: User = { id: 2, nickname: "sunbin" };

โœ… interface์—์„œ ์˜ต์…”๋„

// interface์˜ ์˜ต์…”๋„ ์‚ฌ์šฉ interface Product { name: string; price?: number; } const p1: Product = { name: "Book" }; const p2: Product = { name: "Bag", price: 50 };

โœ… ํด๋ž˜์Šค์—์„œ ์˜ต์…”๋„ ์†์„ฑ

class Person { name: string; age?: number; constructor(name: string, age?: number) { this.name = name; if (age !== undefined) { this.age = age; } } } let obj: { a: string; b?: string } = { a: "hello", b: "world" }; obj = { a: "hello" }; // b๊ฐ€ ์žˆ์–ด๋„ ๊ทธ๋งŒ ์—†์–ด๋„ ๊ทธ๋งŒ,

๐Ÿ“Œ 2. ์ œ๋„ค๋ฆญ (Generic)

โœ… ๊ฐœ๋…

์ œ๋„ค๋ฆญ์ด๋ž€ ํƒ€์ž…์„ ๋งค๊ฐœ๋ณ€์ˆ˜์ฒ˜๋Ÿผ ์ „๋‹ฌ๋ฐ›์•„ ์‚ฌ์šฉํ•˜๋Š” ๋ฐฉ์‹์ž…๋‹ˆ๋‹ค.

โœ… ์ œ๋„ˆ๋ฆญ์„ ์‚ฌ์šฉํ•˜๋Š” ์ด์œ 

function add(x: string | number, y: string | number): string | number { return x + y; } // ํƒ€์ž…์Šคํฌ๋ฆฝํŠธ๋Š” ๋ชจ๋“  ๊ฒฝ์šฐ๋ฅผ ๋‹ค ๊ณ ๋ คํ•˜๊ธฐ ๋•Œ๋ฌธ์— 2 * 2์˜ ๋ชจ๋“  ์ƒํ™ฉ์„ ๊ณ ๋ ค // ๊ฒฐ๊ณผ๋ฅผ ์ด๋ ‡๊ฒŒ ๋งŒ๋“ค๊ฒƒ์œผ๋กœ ์ƒ๊ฐ ํ•˜๊ณ  ๋งŒ๋“ค์—ˆ์ง€๋งŒ, add(1, 2); // 3 add("1", "2"); //12 // ์ด๋Ÿฐ ๋ชจ๋“  ์ผ€์ด์Šค๋“ค์— ๋Œ€ํ•ด์„œ๋„ ๊ณ ๋ คํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์˜ฌ๋ฐ”๋ฅธ ํ•จ์ˆ˜๋ผ๊ณ  ๋ณผ ์ˆ˜ ์—†์Œ add(1, "2"); //12 add("1", 2); //12

ํ•˜๋‚˜์˜ ํ•จ์ˆ˜ ๋ช…์œผ๋กœ ๋‘๊ฐ€์ง€ ๊ธฐ๋Šฅ์„ ๋™์‹œ์— ์ฒ˜๋ฆฌํ•˜๋„๋ก ํ•˜๊ณ  ์‹ถ์ง€๋งŒ, ๋‹ค์Œ๊ณผ ๊ฐ™์€ ๋ฐฉ๋ฒ•์œผ๋กœ๋Š” ์ฒ˜๋ฆฌ ํ•  ์ˆ˜ ์—†์Œ

// ๋™์ผํ•œ ๊ฐฏ์ˆ˜์˜ ๋งค๊ฐœ๋ณ€์ˆ˜๋Š” ์˜ค๋ฒ„ ๋กœ๋”ฉ ๋ถˆ๊ฐ€๋Šฅ function add(x: string, y: string): string; function add(x: number, y: number): number;

โœ… ๊ธฐ๋ณธ ์˜ˆ์‹œ

// ์ œ๋„ˆ๋ฆญ // ๋™์ผ ํƒ€์ž…์„ ์‚ฌ์šฉํ•˜๊ณ , // T๋ผ๊ณ  ํ‘œ๊ธฐํ•ด ๋‘์—ˆ์ง€๋งŒ, ์–ด๋–ค ๋ฌธ์ž๋กœ๋“  ๋‹ค ๊ธฐ์ž… ๊ฐ€๋Šฅํ•˜๋‹ค. function add<T>(x: T, y: T): T { return x + y; } // ์ œ๋„ˆ๋ฆญ์€ ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ• ๋•Œ ํƒ€์ž…์ด ์ •ํ•ด์งˆ ์ˆ˜ ์žˆ๊ฒŒ ์‚ฌ์šฉํ•œ๋‹ค. add(1, 2); add("1", "2"); add<number>(1, 2); add<string>("1", "2"); // ์—ฌ์ „ํžˆ ์˜ค๋ฅ˜ // add(1, "2") // โŒ ํƒ€์ž… ๋ถˆ์ผ์น˜ ์—๋Ÿฌ

โœ… ํƒ€์ž… ์ œํ•œ (extends)

// ๋ฒ”์œ„๊ฐ€ ๋„ˆ๋ฌด ๋„“๋‹ค๊ณ  ํŒ๋‹จ๋  ๊ฒฝ์šฐ, T์— ์ œํ•œ์„ ๋‘˜์ˆ˜ ์žˆ๋‹ค. function add<T extends string>(x: T, y: T): T { return x + y; } // ๋งค๊ฐœ๋ณ€์ˆ˜ ๋งŒ์€ ๊ฐ™์€ ํƒ€์ž…์ด ๋“ค์–ด๊ฐˆ ์ˆ˜ ์žˆ๋„๋ก ํ•  ์ˆ˜ ์žˆ๋‹ค. function add<T extends string | number>(x: T, y: T): T { return x + y; } // ์—ฌ๋Ÿฌ ๊ฐœ์˜ ์ œ๋„ˆ๋ฆญ๋„ ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•˜๋‹ค. function add<T extends string | number, K extends string>(x: T, y: T): T { return x + y; }

โœ… ์ œ๋„ค๋ฆญ ์„ ์–ธ ์œ„์น˜ ๊ธฐ์–ตํ•˜๊ธฐ

function a<T>() {} class B<T>() {} interface C<T> {} type D<T> = {}; const e = <T>() => {};

๐Ÿ“Œ 3. ์ œ๋„ค๋ฆญ ๋‹ค์–‘ํ•œ ํ™œ์šฉ ์˜ˆ์‹œ

โœ… 1 - ๊ฐ์ฒด ํƒ€์ž… ์ œ์•ฝ

// ํŠน์ • ๊ฐ์ฒด // <T extends {...}> function printA<T extends { a: string }>(obj: T): void { // โœ… TypeScript only: obj must have string `a` console.log(obj.a); } printA({ a: "hello" }); // โœ… OK printA({ a: "world", extra: 123 }); // โœ… OK // printA({ b: "oops" }); // โŒ TS error: a๊ฐ€ ์—†์Œ

โœ… 2 - ๋ฐฐ์—ด ํƒ€์ž… ์ œ์•ฝ

// ๋ชจ๋“  ๋ฐฐ์—ด // <T extends any[]> function getList<T extends string[]>(x: T): T { return x; } getList(["1", "2", "3"]); function getFirst<T extends any[]>(arr: T): T[number] { // โœ… TypeScript only: ๋ฐฐ์—ด์˜ ์š”์†Œ ํƒ€์ž…์„ ์ž๋™ ์ถ”๋ก ํ•จ return arr[0]; } const x = getFirst(["a", "b"]); // string ์ถ”๋ก ๋จ const y = getFirst([1, 2, 3]); // number ์ถ”๋ก ๋จ

โœ… 3 - ํ•จ์ˆ˜ ํƒ€์ž… ์ œ์•ฝ

// ํ•จ์ˆ˜ ํƒ€์ž… // <T extends (...args: any) => any> // ๋ชจ๋“  ํ•จ์ˆ˜ // (...args: any) => any ๋ชจ๋“  ํ•จ์ˆ˜ ์ž…๋ ฅ (any๋ฅผ ์จ๋„ ๋˜๋Š” ์œ ์ผํ•œ ์˜ˆ์™ธ) // ์ž…๋ ฅ๋ฐ›๋Š” ์ฝœ๋ฐฑ ํ•จ์ˆ˜์˜ ํ˜•ํƒœ๋ฅผ ์ง€์ •ํ•œ๋‹ค. function add<T extends (a: string) => number>(x: T): T { return x; } function useCallback<T extends (...args: any[]) => any>(fn: T): void { // โœ… TypeScript only: fn์€ ํ•จ์ˆ˜ ํƒ€์ž…์ด์–ด์•ผ ํ•จ fn(); // args ์—†์œผ๋ฉด undefined๋กœ ํ˜ธ์ถœ๋จ } useCallback(() => console.log("hello")); // OK // ์ž…๋ ฅ ํ˜•ํƒœ ๊ณ ์ • function runCallback<T extends (msg: string) => void>(fn: T): void { fn("TypeScript"); } runCallback((text) => console.log(text.length)); // OK

โœ… 4 - ์ƒ์„ฑ์ž ํƒ€์ž… ์ œ์•ฝ

// ์ƒ์„ฑ์ž ํƒ€์ž… // <T extends abstract new (...args: any) => any> function add<T extends abstract new (...args: any) => any>(x: T): T { return x; } // ํด๋ž˜์Šค ์ž์ฒด๋ฅผ ๋„ฃ๊ณ  ์‹ถ์„๋•Œ class A {} add(A); add(new A()); // ์˜ค๋ฅ˜ function create<T extends abstract new (...args: any[]) => any>(Ctor: T): InstanceType<T> { // โœ… TypeScript only: ์ƒ์„ฑ์ž๋กœ๋งŒ ํ˜ธ์ถœ ๊ฐ€๋Šฅ return new Ctor(); } class MyClass { msg = "hi"; } const obj = create(MyClass); console.log(obj.msg); // "hi"

โœ… 5 - ํ‚ค ํƒ€์ž… ์ œํ•œ (keyof any)

// <T extends keyof any> // string | number | symbol // ๋ชจ๋“  ํ‚ค๋“ค์„ ๋ฐ›๊ณ  ์‹ถ์„๋•Œ function logKey<T extends keyof any>(key: T) { // โœ… TypeScript only: ํ‚ค ํƒ€์ž…๋งŒ ํ—ˆ์šฉ (string | number | symbol) console.log(`Key is: ${String(key)}`); } logKey("name"); // โœ… OK logKey(42); // โœ… OK logKey(Symbol("id")); // โœ… OK

๐ŸŸฆ Symbol์ด๋ž€?

Symbol์€ ๊ณ ์œ ํ•˜๊ณ  ์ถฉ๋Œํ•˜์ง€ ์•Š๋Š” ์‹๋ณ„์ž๋ฅผ ๋งŒ๋“ค๊ธฐ ์œ„ํ•œ ์›์‹œ ํƒ€์ž…(primitive type)

Symbol์€ ํ‚ค ์ด๋ฆ„ ์ถฉ๋Œ์„ ๋ฐฉ์ง€ํ•  ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์—, ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ๋‚ด๋ถ€๋‚˜ ๋ฉ”ํƒ€๋ฐ์ดํ„ฐ ๋“ฑ์— ์ž์ฃผ ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค.

const sym1 = Symbol("id"); const sym2 = Symbol("id"); console.log(sym1 === sym2); // false โ— ์„œ๋กœ ๋‹ค๋ฆ„ // ์‚ฌ์šฉ์˜ˆ์ œ // ๊ฐ์ฒด ํ‚ค๋กœ ์‚ฌ์šฉ: const id = Symbol("id"); const user = { name: "sunbin", [id]: 12345 }; console.log(user[id]); // 12345
Last updated on