Skip to content
Benedict edited this page Nov 6, 2023 · 8 revisions

준비하기

nodejs 최신버전 vscode

// npm을 처음 사용한다면
Set-ExecutionPolicy Unrestricted

// typescript 설치
npm install -g typescript

// ts -> js 자동 변환
tsc -w

기본 문법

// 기본 타입
// string, number, boolean, bigint, null, undefined,[], {} ...
let familyName: string = 'lee';
let familyNames: string[] = ['lee', 'kim', 'park']
let profile: { age: number } = { age: 20 }


// 유니온 Union 타입
let unionTest: string | number = 'lee';


// 미리 정의한 타입
type PreDefType = string | number;
let typedefTest: PreDefType = 'lee';


// Tuple 타입
type TupleType = [number, boolean, string];
let tupleTest: TupleType = [100, true, 'str']


// Obj 타입
type personType = {
  name: string,
  age: number,
  married?: boolean, // optional
}
let objTypeTest: personType = {
  name: 'lee',
  age: 20,
  married: true
} // valid
let objTypeTest: personType = {
  name: 'kim',
  age: 35,
} // also valid


// 리터럴 타입
type LiteralType = 'lee' | 'kim' | 'park';
let literalTypeTest: LiteralType = 'lee';


// 함수 타입
function mul1(x: number): number {
  return x * 2
}


// Union을 모호하게 사용 -> 컴파일 오류
function mul2(x: number | string) {
  //return x * 2 // Error : The left-hand side of an arithmetic operation must be of type 'any', 'number', 'bigint' or an enum type.ts(2362)
}


// Union을 명시적 사용
function mul3(x: number | string) {
  if (typeof x === 'number') {
    return x * 2
  }
}


// 클래스 맴버 타입
class Person {
  name;
  constructor(name: string) {
    this.name = name;
  }
}


// 일관된 key 타입을 가진 obj 타입
type personStrType = {
  [key: string]: string,
}
let strObjTypeTest: personStrType = {
  name: 'lee',
  age: '20',
  married: 'true',
}
let strObjTypeTest: personStrType = {
  name: 'lee',
  age: 20, // error
  married: 'true',
}


// number type key
type numKeyType = {
  [key: number]: string,
}
type numKeyType2 = string[]
let numKeyTypeTest: numKeyType = ['hello', 'world']
expect(numKeyTypeTest2[0]).toBe('hello')


// mixtype key
type mixKeyType{
  [key: number]: string
  [key: string]: string
}
let mixKeyTypeTest : mixKeyType = {
  0: "hello",
  value: "world",
}
expect(mixKeyTypeTest[0]).toBe('hello')
expect(mixKeyTypeTest['value']).toBe('world')

Narrowing

function increment(x: number | string) {
  return x + 1 // error
}


// Narrowing 1 - typeof
function inc_typeof(x: number | undefined) {
  if (typeof x === 'number') {
    return x + 1
  } else {
    return NaN
  }
}
expect(inc_typeof(1)).toBe(2)
expect(inc_typeof(undefined)).toBe(NaN)


// Narrowing 2 - check undefined
function inc_check_undefined(x: number | undefined) {
  if (x) {
    return x + 1
  }
  return NaN
}
expect(inc_check_undefined(1)).toBe(2)
expect(inc_check_undefined(undefined)).toBe(NaN)


// Narrowing 3 - assertion - 타입을 주장할 뿐, 실제로 변환해주지는 않음
function inc_assertion(x: number | undefined) {
  return (x as number) + 1
}
expect(inc_assertion(1)).toBe(2)
expect(inc_assertion(undefined)).toBe(NaN)


// Narrowing 4 - in
type Fish = { swim: string };
type Bird = { fly: string };
function printMsg4(msg: Fish | Bird) {
  if ("swim" in msg) {
    console.log(msg.swim);
  } else if ("fly" in msg) {
    console.log(msg.fly);
  } else {
    // Do Nothing
  }
}


// Narrowing 5 - instanceof
class Knight {
  Sword(): string { return "Knight - Sword"; }
}
class Mage {
  Magic(): string { return "Mage - Magic"; }
}
function printMsg5(msg: Knight | Mage) {
  if (msg instanceof Knight) {
    console.log(msg.Sword());
  } else if (msg instanceof Mage) {
    console.log(msg.Magic());
  } else {
    // Do Nothing
  }
}


// Narrowing 6 - literal type
type Fish2 = { swim: string, where: 'sea' };
type Bird2 = { fly: string, where: 'sky' };
function printMsg6(msg: Fish2 | Bird2) {
  if (msg.where === 'sea') {
    console.log(msg.swim);
  } else if (msg.where === 'sky') {
    console.log(msg.fly);
  } else {
    // Do Nothing
  }
}

Clone this wiki locally