카테고리 없음

TypeScript 객체와 타입

만능 엔터테이너 2024. 7. 27. 16:35
728x90
반응형
SMALL
name과 age라는 속성을 가진 클래스 선언

class Person1 {
  name: string
  age?: number
}

자바스크립트 & 타입스크립트의 기본 타입

유형 자바스크립트 타입 타입스크립트 타입
수 타입 Number number
불리언 타입 Boolean boolean
문자열 타입 String string
객체 타입 Object object

 

타입 주석

자바스크립트 변수 선언문을 확장하여 타입을 명시합니다.

 

let 변수 이름: 타입 [=초깃값]

const 변수 이름: 타입 = 초깃값

<타입스크립트 변수 선언문 예시>

let n: number = 1
let b: boolean = true or false
let s: string = 'hello'
let o: object = {}

 

📌TypeScript는 JavaScript와 다르게 let으로 선언한 변숫값은 타입 주석으로 명시한 타입해 해당하는 값으로만 변경이 가능합니다.

 

타입 추론

TypeScript는 JavaScript와의 호환성을 위해 타입 주석 부분을 생략할 수 있습니다.

TypeScript 컴파일러는 다음과 같은 코드를 만나면 대입연산자 = 오른쪽 값에 따라 변수의 타입을 지정합니다.

let n = 1 // n의 타입을 number로 판단
let b = true // b의 타입을 boolean으로 판단
let s = 'hello' // s의 타입을 string으로 판단
let o = {} // o의 타입을 object로 판단

 

any 타입

타입과 무관하게 어떤 종류의 값도 저장할 수 있습니다.

let a: any = 0
a = 'hello'
a = true
a = {}

 

undefined 타입

JavaScript에서는 undefined는 값입니다. 그러나 TypeScript에서는 undefined는 타입이기도 하고 값이기도 합니다.

let u: undefined = undefinend
u =1 // Type '1' is not assignable to type 'undefined' 오류 발생

 

1행에서 u는 undefined 타입으로 명시하여 undefined 값만 사용이 가능합니다.

2행에서는 undefined의 상위 타입인 number 타입 1을 저장하려고 했으므로 오류가 발생하는 것이빈다.

 

최상위 타입 - any

number,boolean,sring ...       object

...

최하위 타입 - undefined

 

템플릿 문자열

변수에 담긴 값을 조합하여 문자열을 만들 수 있습니다. 역따옴표(백틱)`로 문자열을 감싸고 변수를 ${} 기호로 감싸는 형태로 만듭니다.

`${변수 이름}`
let count = 10, message = 'Your count'
let result = `${message} is ${count}`
console.log(result) // Your count is 10

 

인터페이스 선언문

interface는 객체의 타입을 정의하는 것이 목적, 객체를 의미하는 중괄호 {}로 속성의 이름과 타입을 나열하는 형태로 사용

interface 인터페이스 이름 {
  속성 이름[?]: 속성 타입[,...]
}

📌, interface 속성은 여러 줄로 구현할 때는 쉼표(,) 대신 세미콜론(;) 또는 줄바꿈으로 구분하여 사용합니다.

인터페이스 구문 예시

interface IPerson {
  name: string
  age: number
}
인터페이스의 조건을 벗어나는 예

interface IPerson {
  name: string
  age: number
}
let good: IPerson = {name: 'Jack', age: 32 }

let bad1: IPerson = { name: 'Jack' } // age 속성이 없으므로 오류
let bad2: IPerson = { age: 32 } // name 속성이 없으므로 오류
let bad3: IPerson = {} // name과 age 속성이 없으므로 오류
let bad4: IPerson = { name: 'Jack', age: 32, etc: true } // etc 속성이 있어서 오류

 

선택 속성 구문

interface를 설계할 때 어떤 속성은 반드시 있어야 하지만, 어떤 속성은 있어도 되고 없어도 되는 형태로 만들고 싶을 때가 있습니다. 이러한 속성을 선택 속성이라고 합니다.

선택 속성은 다음 코드에서 4행처럼 속성 이름 뒤에 물음표 기호를 붙여서 만듭니다.

interface IPerson2 {
  name: string // 필수 속성
  age: number // 필수 속성
  etc?: boolean  // 선택 속성
}

[ 2개의 구문 모두 가능📌 ]
let good1: IPerson2 = {name: 'Jack', age: 32 }
let good2: IPerson2 = {name: 'Jack', age: 32, etc: true }

 

익명 인터페이스

interface 키워드를 사용하지 않고 interface의 이름도 없는 interface를 만들 수 있는데, 이를 익명 인터페이스라고 합니다.

익명 인터페이스 예

let ai: {
  name: string
  age: number
  etc?: boolean
} = { name: 'Jack', age: 32 }

 

익명 인터페이스는 주로 다음처럼 함수를 구현할 때 사용합니다.

함수에 사용된 익명 인터페이스 예

function printMe(me: {name: string, age: number, etc?: boolean}) {
  console.log(
  me.etc?
    `${me.name} ${me.etc}`:
    `${me.name} ${me.age}
  )
}
printMe(ai) // Jack 32

 

클래스 선언문

class 클래스 이름 {
  [private | protected | public] 속성 이름[?]: 속성 타입[...]
}
name과 age라는 속성을 가진 클래스 선언

class Person1 {
  name: string
  age?: number
}

 

접근 제한자

클래스의 속성은 public, private, protect와 같은 접근 제한자를 이름 앞에 붙입니다.

만약, 생략하면 모두 public으로 간주합니다.

 

생성자

contructor 이름의 특별한 메서드를 이용하여 타입스크립트의 클래스를 2행과 같은 형태로 클래스의 속성( name, age)를 선언할 수 있습니다.

class Person2 {
  constructor(public name: string, public age?: number) {}
}
let jack2 : Person2 = new Person2('Jack',32)
console.log(jack2) // Person2 { name: 'Jack', age: 32 }

 

인터페이스 구현

클래스가 인터페이스를 구현할 때는 implements 키워드를 사용합니다.

class 클래스 이름 implements 인터페이스 이름 {
  ...
}

 

이때, 클래스 내부에는 반드시 인터페이스가 정의하고 있는 속성을 멤버 속성으로 포함해야 합니다.

interface IPerson4 {
  name: string
  age?: number
}

class Person4 implements IPerson4 {
  name: string
  age: number
}

 

추상 클래스

abstract 키워드를 사용하여 만듭니다. 추상 클래스는 자신의 속성이나 메서드 앞에 abstract를 붙여 자신을 상속하는 다른 클래스에서 이 속성이나 메서드를 구현합니다.

abstract class 클래스 이름 {
  abstract 속성 이름: 속성 타입
  abstract 메서드 이름() {}
}

 

AbstractPerson5는 name 속성 앞에 abstract가 붙었으므로 new 연산자를 적용하여 객체를 만들 수 없습니다.

추상 클래스 예

abstract class AbstractPerson5 {
  abstract name: string
  constructor(public age?: number)
}

 

클래스의 상속

extends 키워드를 사용하여 상속 클래스를 만듭니다.

class 상속 클래스 extends 부모 클래스 { ... }
class Person5 extends AbstractPerson5 {
  constructor(public name: string, age?: number)
  super(age)
  }
}
let jack5 : Person5 = new Person5('Jack',32)
console.log(jack5) // Person5 { name: 'Jack', age: 32 }

 

static 속성

정적인 속성을 나타낼 때 사용합니다.

class 클래스 이름 {
  static 정적 속성 이름: 속성 타입
}
static 사용 예

class A {
  static initValue = 1
}

let initVal = A.initValue // 1

 

구조화란? 다음처럼 인터페이스나 클래스를 사용하여 관련된 정보를 묶어 새로운 타입으로 표현하는 것을 말합니다.

export interface IPerson {
  name: string
  age: number
}

export interface ICompany {
  name: string
  age: number
}

 

비구조화란? 구조화된 데이터는 아래와 같이 어느 시점에서 데이터의 일부만 사용할 때가 있습니다. 그런데 이러한 시점부터 jack 변수는 더 사용하지 않고 name과 age변수만 사용합니다. 이처럼 구조화된 데이터를 분해하는 것을 비구조화라고 합니다.

let name = jack.name, age = jack.age

 

비구조화 할당

비구조화 할당을 객체에 적용하려면 얻고 싶은 속성을 중괄호 {} 로 묶습니다.

let {name, age} = jack
import {IPerson} from './IPerson_ICompany'

let jack: IPerson = {name: 'Jack', age: 32}
let {name, age} = jack
console.log(name, age) // Jack 32

 

잔여 연산자

... 연산자를 활용하여 사용되는 위치에 따라 잔여 연산자 혹은 전개 연산자라고 부릅니다.

만약, 다음 코드에서 address 변수는 5개 속성을 가지고 있는데, 이 중 country와 city를 제외한 나머지 속성을 별도의 detail이라는 변수에 저장하고 싶다면, 8행에서 보듯 detail 변수 앞에 잔여 연산자를 붙입니다.

잔여 연산자 예

let address: any = {
  country: 'Korea'
  city: 'Seoul'
  address1: 'Gangnam-gu'
  address2: 'Sinsa-dong 123-456'
  address3: '789 street, 2 Floor ABC building'
}
const {country, city, ...detail} = address
console.log(detail)

 

실행결과로는 detail 변수에 address1,2,3의 정보가 저장되어 출력됩니다.

 

전개 연산자

... 점 3개 연산자가 비구조화 할당문이 아닌 곳에서 사용될 때 이를 전개 연산자라고 합니다.

let part1 = {name: 'jane'}, part2 = {age: 22}, part3 = {city: 'Seoul', country: 'Kr'}
let merged = {...part1, ...part2, ...part3 }
console.log(merged)

실행 결과
{ name: 'jane', age: 22, city: 'Seoul', country: 'Kr' }

 

 

타입 변환

타입 변환으로 번역되는 3가지 프로그래밍 용어로는 'type conversion' , 'type casting' , 'type coercion' 이 있습니다. types coersion은 type casting과 type coercion을 모두 포함하는 용어이고 type casting은 명시적 변환 / type coercion은 암시적 형 변환입니다.

 

 

타입 단언

타입스크립트는 타입 변환이 아닌 타입 단언 이라는 용어를 사용합니다.

아래는 타입 단언문의 2가지 형태 입니다. 형태는 다르지만 기능은 동일합니다!

(<타입>객체)

(객체 as 타입)
import INameable from './INameable'
let obj: object = {name: 'Jack'}

let name1 = (<INameab0le>).name
let name2 = (obj aw INameable).name
console.log(name1, name2) // Jack Jack

 

728x90
반응형
LIST