2. TypeScript

ํ‚ค์›Œ๋“œ

  • REPL

  • TypeScript

    • ํƒ€์ž… ์ถ”๋ก 

    • Interface vs Type

    • Union Type vs Intersection Type

    • Optional Parameter

ํƒ€์ž…์Šคํฌ๋ฆฝํŠธ, ์™œ ์“ฐ๋Š”๊ฐ€?

  • ํŽธ๋ฆฌํ•œ ์ž๋™์™„์„ฑ

  • ์‹ค์‹œ๊ฐ„ ์˜ค๋ฅ˜๊ฒ€์‚ฌ

REPL

  • Read-Eval-Print-Loop

  • ์‚ฌ์šฉ์ž์˜ ์ž…๋ ฅ์„ ๋ฐ›์•„ ํ‰๊ฐ€ํ•˜๊ณ  ๊ฒฐ๊ณผ๋ฅผ ๋ฆฌํ„ดํ•˜๋Š” ์ธํ„ฐ๋ ‰ํ‹ฐ๋ธŒ ํ”„๋กœ๊ทธ๋ž˜๋ฐ ํ™˜๊ฒฝ

  • ts-node๋ฅผ ์‹คํ–‰ํ•ด ํƒ€์ž…์Šคํฌ๋ฆฝํŠธ REPL ์‚ฌ์šฉ ๊ฐ€๋Šฅ npx ts-node

ํƒ€์ž… ์ถ”๋ก 

ํƒ€์ž…์Šคํฌ๋ฆฝํŠธ๋Š” ์ž๋ฃŒ์˜ ๋’ค์— ํƒ€์ž…์„ ๋ช…์‹œ

ํƒ€์ž…์„ ๋ช…์‹œํ•˜์ง€ ์•Š์•„๋„ ๊ฐ’์„ ํ†ตํ•ด ์ž๋™์œผ๋กœ ํƒ€์ž…์„ ๊ฒฐ์ •ํ•ด์ฃผ๊ธฐ๋„ ํ•จ

const name: string = 'ํ™๊ธธ๋™';
const name = 'ํ™๊ธธ๋™';
// ์œ„์˜ ์ฝ”๋“œ์™€ ์•„๋ž˜์ฝ”๋“œ๋Š” ๊ฐ™๋‹ค.

ํƒ€์ž…

์›์‹œํƒ€์ž…

let name: string;
let age: number;
let isAdult: boolean;

name = "ํ™๊ธธ๋™";
age = 20;
isAdult = true;

๋ฐฐ์—ด

number[] ๋˜๋Š” Array<number> ์˜ ํ˜•ํƒœ๋กœ ์‚ฌ์šฉ

let numbers: number[];
numbers = [1, 2, 3];

ํŠœํ”Œ

๊ธธ์ด์™€ ํƒ€์ž…์ด ๊ณ ์ •๋œ ๋ฐฐ์—ด

์ˆœ์„œ์— ๋งž์ง€ ์•Š๊ฒŒ ๋ฐ์ดํ„ฐ๋ฅผ ๋„ฃ์œผ๋ฉด ์—๋Ÿฌ ํ‘œ์‹œ

let user1: [number, string, string];
user1 = [1, 'setType77@example.com', '1q2w3e4r'];

ํ•œ๊ณ„์ 

push ๋ฉ”์„œ๋“œ๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ์ •์˜์™€ ์ƒ๊ด€์—†์ด ๋ฐฐ์—ด์˜ ๊ธธ์ด๊ฐ€ ๋Š˜์–ด๋‚จ

let user1: [number, string, string];
user1 = [1, 'setType77@example.com', '1q2w3e4r'];

user1.push('fake'); // ์—๋Ÿฌ์—†์ด ์ปดํŒŒ์ผ๋ฉ๋‹ˆ๋‹ค.

ํ•ด๊ฒฐ๋ฐฉ์•ˆ

ํŠœํ”Œ ์„ ์–ธ์‹œ์— readonly ์‚ฌ์šฉ

type UserInfo = readonly [number , string, string ,string , boolean]; // ๋ฐฐ์—ด ์•ž์— readonly ์ ์šฉ

let userInfo1 : UserInfo = [1, 'user1@example.com' , 'abcd123' , '1999-01-01' , true];

userInfo1.push('hello'); // Error

any

์–ด๋–ค ๊ฐ’์˜ ํƒ€์ž…์ด any์ด๋ฉด ํƒ€์ž… ๊ฒ€์‚ฌ๋ฅผ ์‹คํ–‰ํ•˜์ง€ ์•Š์Œ

ํ•จ์ˆ˜

๋งค๊ฐœ๋ณ€์ˆ˜์™€ ๋ฆฌํ„ด๊ฐ’์— ํƒ€์ž…์„ ํ‘œ๊ธฐํ•  ์ˆ˜ ์žˆ์Œ

// ๋งค๊ฐœ๋ณ€์ˆ˜ ํƒ€์ž… ํ‘œ๊ธฐ
function greet(name: string) {
  console.log("Hello, " + name.toUpperCase() + "!!");
}

// ๋ฐ˜ํ™˜ ํƒ€์ž… ํ‘œ๊ธฐ
function getFavoriteNumber(): number {
  return 26;
}

๋ฌธ๋งฅ์„ ํ†ตํ•ด ์ต๋ช… ํ•จ์ˆ˜์˜ ํƒ€์ž…์„ ์ถ”๋ก ํ•  ์ˆ˜ ์žˆ๋‹ค๋ฉด, ์ž๋™์œผ๋กœ ํƒ€์ž…์ด ๋ถ€์—ฌ๋จ

const names = ["Alice", "Bob", "Eve"];
 
names.forEach(function (s) {
  console.log(s.toUppercase());
  //Property 'toUppercase' does not exist on type 'string'. Did you mean 'toUpperCase'?
});
 
names.forEach((s) => {
  console.log(s.toUppercase());
  //Property 'toUppercase' does not exist on type 'string'. Did you mean 'toUpperCase'?
});

๊ฐ์ฒด

let human: {
  name: string;
  age: number;
};

human = { name: 'ํ™๊ธธ๋™', age: 13 };

Optional parameter

๊ฐ์ฒด์˜ ์†์„ฑ์„ ์˜ต์…˜ํ™”ํ•˜๊ฑฐ๋‚˜ ํ•จ์ˆ˜์˜ ๋งค๊ฐœ๋ณ€์ˆ˜๋ฅผ ์˜ต์…˜ํ™”ํ•  ์ˆ˜ ์žˆ์Œ

function printName(obj: { first: string; last?: string }) {
  // ...
}
// ๋‘˜ ๋‹ค OK
printName({ first: "Bob" });
printName({ first: "Alice", last: "Alisson" });
function greeting(name?: string): string {
  return `Hello, ${name || 'world'}`;
}

Union vs. Intersection

๊ธฐ์กด์˜ ํƒ€์ž…์„ ๊ธฐ๋ฐ˜์œผ๋กœ ๋‹ค์–‘ํ•œ ์—ฐ์‚ฐ์ž๋ฅผ ์‚ฌ์šฉํ•ด์„œ ์ƒˆ๋กœ์šด ํƒ€์ž…์„ ๋งŒ๋“ค ์ˆ˜ ์žˆ์Œ

Union Type

์ˆซ์ž ๋˜๋Š” ๋ฌธ์ž๋ฅผ ๋ฐ›์„ ์ˆ˜ ์žˆ๋Š” ํ•จ์ˆ˜

function printId(id: number | string) {
  console.log("Your ID is: " + id);
}
// OK
printId(101);
// OK
printId("202");
// ์˜ค๋ฅ˜
printId({ myID: 22342 });

์œ ๋‹ˆ์–ธ์„ ์‚ฌ์šฉํ•  ๋•Œ๋Š” ํ•ด๋‹น ์œ ๋‹ˆ์–ธ ํƒ€์ž…์˜ ๋ชจ๋“  ๋ฉค๋ฒ„์— ๋Œ€ํ•ด ์œ ํšจํ•œ ์ž‘์—…๋งŒ ํ—ˆ์šฉ๋จ

string | number ์œ ๋‹ˆ์–ธ ํƒ€์ž…์˜ ๊ฒฝ์šฐ, string ํƒ€์ž…์—๋งŒ ์œ ํšจํ•œ ๋ฉ”์„œ๋“œ๋Š” ์‚ฌ์šฉํ•  ์ˆ˜ ์—†์Œ

function printId(id: number | string) {
  console.log(id.toUpperCase());
  // Property 'toUpperCase' does not exist on type 'string | number'.
  // Property 'toUpperCase' does not exist on type 'number'.
}

typeof๋ฅผ ์ด์šฉํ•ด ๋ถ„๊ธฐ ์ฒ˜๋ฆฌ

function printId(id: number | string) {
  if (typeof id === "string") {
    // ์ด ๋ถ„๊ธฐ์—์„œ id๋Š” 'string' ํƒ€์ž…์„ ๊ฐ€์ง‘๋‹ˆ๋‹ค
 
    console.log(id.toUpperCase());
  } else {
    // ์—ฌ๊ธฐ์—์„œ id๋Š” 'number' ํƒ€์ž…์„ ๊ฐ€์ง‘๋‹ˆ๋‹ค
    console.log(id);
  }
}

Intersection Type

์—ฌ๋Ÿฌ ํƒ€์ž…์„ ๋ชจ๋‘ ๋งŒ์กฑํ•˜๋Š” ํ•˜๋‚˜์˜ ํƒ€์ž…

interface Person {
  name: string;
  age: number;
}
interface Developer {
  name: string;
  skill: number;
}
type Capt = Person & Developer;

Capt ํƒ€์ž…์€ ์•„๋ž˜์™€ ๊ฐ™์ด ์ •์˜๋จ

{
  name: string;
  age: number;
  skill: string;
}

Type vs. Interface

type

๋˜‘๊ฐ™์€ ํƒ€์ž…์„ ์žฌ์‚ฌ์šฉํ•˜๊ฑฐ๋‚˜ ๊ฐ์ฒด, ์œ ๋‹ˆ์–ธ ํƒ€์ž… ๋“ฑ์„ ๋” ๊ฐ„๋‹จํ•œ ์ด๋ฆ„์œผ๋กœ ๋ถ€๋ฅด๊ณ  ์‹ถ์€ ๊ฒฝ์šฐ ํƒ€์ž…์˜ ๋ณ„์นญ์„ ๋งŒ๋“ค ์ˆ˜ ์žˆ์Œ

type Point = {
  x: number;
  y: number;
};
 
function printCoord(pt: Point) {
  console.log("The coordinate's x value is " + pt.x);
  console.log("The coordinate's y value is " + pt.y);
}
 
printCoord({ x: 100, y: 100 });
type ID = number | string;

interface

type๊ณผ ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ ๊ฐ์ฒด ํƒ€์ž…์„ ๋งŒ๋“œ๋Š” ๋˜ ๋‹ค๋ฅธ ๋ฐฉ๋ฒ•

interface Point {
  x: number;
  y: number;
}
 
function printCoord(pt: Point) {
  console.log("The coordinate's x value is " + pt.x);
  console.log("The coordinate's y value is " + pt.y);
}
 
printCoord({ x: 100, y: 100 });

type๊ณผ interface์˜ ์ฐจ์ด์ 

์ธํ„ฐํŽ˜์ด์Šค๋Š” ๊ฐ์ฒด์—๋งŒ ์‚ฌ์šฉ๋˜๋ฉฐ, ์›์‹œํƒ€์ž…์— ์ด๋ฆ„์„ ๋ถ€์—ฌํ•˜๋Š” ๋ฐ๋Š” ์‚ฌ์šฉํ•  ์ˆ˜ ์—†์Œ

์ธํ„ฐํŽ˜์ด์Šค๋Š” extends๋ฅผ ํ†ตํ•ด ํ™•์žฅ, ํƒ€์ž…์€ ๊ต์ง‘ํ•ฉ์„ ํ†ตํ•ด ํ™•์žฅ

interface Animal {
  name: string
}

interface Bear extends Animal {
  honey: boolean
}

const bear = getBear()
bear.name
bear.honey
type Animal = {
  name: string
}

type Bear = Animal & {
  honey: Boolean
}

const bear = getBear();
bear.name;
bear.honey;

์ธํ„ฐํŽ˜์ด์Šค๋Š” ์ƒˆ ํ•„๋“œ๋ฅผ ์ถ”๊ฐ€ํ•  ์ˆ˜ ์žˆ์ง€๋งŒ, ํƒ€์ž…์€ ์ƒ์„ฑํ•œ ๋’ค ๋‹ฌ๋ผ์งˆ ์ˆ˜ ์—†์Œ

interface Window {
  title: string
}

interface Window {
  ts: TypeScriptAPI
}

const src = 'const a = "Hello World"';
window.ts.transpileModule(src, {});
type Window = {
  title: string
}

type Window = {
  ts: TypeScriptAPI
}

 // Error: Duplicate identifier 'Window'

Last updated