객체 타입

zimablue·2023년 8월 13일

typescript

목록 보기
3/18

함수의 매개변수가 객체일 때 Type Annotation


매개변수로 받을 객체의 타입을 Annotation할 수 있습니다.

// const 함수 = (매개변수: { key: type; }) => {}

const printName = (person: { first: string; last: string }): void => {
  console.log(`${person.first} ${person.last}`);
};

printName({ first: "Thomas", last: "Jankins" });

초과 프로퍼티

함수를 호출 할 때 객체를 인수로 사용하면, 매개변수에서 Annotation 한 타입 외의 객체 리터럴은 오류를 발생시킵니다.

하지만 사전에 변수에 초기화 하여 호출할 경우 지정된 프로퍼티 외에는 무시합니다.

const printName = (person: { first: string; last: string }): void => {
  console.log(`${person.first} ${person.last}`);
};


// age는 printName 함수 매개변수의 type annotation에 포함되지 않음
// Argument of type '{ first: string; last: string; age: number; }' is not assignable to parameter of type '{ first: string; last: string; }'.
printName({ first: "Thomas", last: "Jankins", age: 32});


// age가 printName 함수 매개변수의 type annotation에 포함되지 않았지만 에러 없음
const singer = { first: "Mick", last: "Jagger", age: 473 };
printName(singer);





변수의 객체를 초기화 할 때 Type Annotation


변수에 담길 객체의 타입을 Annotation할 수 있습니다

// let 변수: { key: 타입; } = 값

let cordinate: { x: number; y: number } = { x: 34, y: 2 };





함수의 return 이 객체일 때 Type Annotation


함수의 반환값이 객체일 경우 Type Annotation을 할 수 있습니다.

// function 함수(): { key: 타입; } {
// 		return { key: value }
// }

function randomCoordinate(): { x: number; y: number } {
  return { x: Math.random(), y: Math.random() };
}





Type Alias


타입에 별칭을 붙일 수 있습니다.
별칭을 생성해 사용하면 불필요한 중복을 피할 수 있습니다.

별칭 생성 전

// 매개변수와 반환값에 { x: number; y: number } 객체가 중복되어 사용됨
  function doublePoint(point: { x: number; y: number }): { x: number; y: number } {
    return { x: point.x * 2, y: point.y * 2 };
  }

참조 타입 별칭 생성

type Point = {
  x: number;
  y: number;
};

// Point라는 별칭 사용
function doublePoint(point: Point): Point {
  return { x: point.x * 2, y: point.y * 2 };
}

console.log(doublePoint({x: 1, y: 2}))
// {"x": 2, "y": 4}

원시 타입 별칭 생성

type MyNum = number;

let age: MyNum = 24234;



특정 값을 가진 concrete type

일반적인 concrete type이 아닌 특정 값으로 type을 지정할 수 있습니다.

type Team = "read" | "blue" | "yellow"
type Health = 1 | 5 | 10

type Player = {
  nickname: string,
  team: Team,
  health: Health
}

const zima :Player = {
  nickname: "zima",
  team: "blue",
  health: 10
}





중첩 객체


중첩 객체사용할 때 별칭이 없다면 가독성이 떨어지게 됩니다.

// 함수
function calculatePayout (song: {
  title: string, 
  artist: string, 
  numStreams: number, 
  credits: {
    producer: string, 
    writer: string
  }
}): number {
  return song.numStreams * 0.0033
};

// 변수에 객체 초기화
const mySong: {
  title: string, 
  artist: string, 
  numStreams: number, 
  credits: {
    producer: string, 
    writer: string
   = {
  title: "Unchained Melody",
  artist: "Righteous Brothers",
  numStreams: 12873321,
  credits: {
    producer: "Phil Spector",
    writer: "Alex North",
  },
};

// 함수 호출
const earnings = calculatePayout(mySong);

별칭 사용

// 별칭 생성
type Song = {
  title: string;
  artist: string;
  numStreams: number;
  credits: {
    producer: string;
    writer: string;
  };
};

// 함수
function calculatePayout(song: Song): number {
  return song.numStreams * 0.0033;
}

// 변수에 객체 초기화
const mySong: Song = {
  title: "Unchained Melody",
  artist: "Righteous Brothers",
  numStreams: 12873321,
  credits: {
    producer: "Phil Spector",
    writer: "Alex North",
  },
};

// 함수 호출
const earnings = calculatePayout(mySong);





선택적 프로퍼티 ( ? )


프로퍼티에 ?(Optional)을 사용하여 선택적 요소로 만들 수 있습니다.
선택적 요소가 된 프로퍼티는 사용되지 않아도 오류가 발생하지 않습니다.

type Point = {
  x: number;
  y: number;
  // z는 있어도, 없어도 상관없음
  z?: number;
};

const myPoint: Point = { x: 1, y: 3, z:9 };

const myPoint: Point = { x: 1, y: 3 };

// Property 'y' is missing in type '{ x: number; z: number; }' but required in type 'Point'
const myPoint: Point = { x: 1, z:9 };



주의점

선택적 프로퍼티를 사용했다면 선택적 요소에는 값이 undefined일 수도 있다는 말과 동일합니다.
따라서 선택적 요소를 조건으로 사용할 때 먼저 선택적 요소의 값이 있는지 확인해야합니다.

const player : {
  name: string,
  age?: number
} = {
  name: "zima"
}

// 에러 Object is possibly 'undefined'
if(player.age < 10) {
  return player.age;
}

// player.age가 있는지 부터 확인
if(player.age && player.age < 10) {
  return player.age;
}





readonly


readonly 제어자로 표시한 프로퍼티는 읽기만 가능하고 쓰기를 할 수 없습니다.

type User = {
  readonly id: number;
  username: string;
};


const user: User = {
  id: 12837,
  username: "zimablue",
};

// Cannot assign to 'id' because it is a read-only property
// id는 readonly이기 때문에 값 재할당 불가능
user.id = 23487104

console.log(user.id)
// 12837

readonly를 사용한 배열에는 값을 추가하지 못합니다.

const numbers: readonly number[] = [1, 2, 3, 4]

// property 'push' does not exist on type 'readonly'
numbers.push(5)

자바스크립트로 컴파일 되었을 때는 readonly가 사라집니다.

// 타입스크립트

const names: readonly string[] = ["1", "2"]
// 자바스크립트로 컴파일

const names = ["1", "2"]





Intersection Type


&를 사용하여 교차 타입을 만들 수 있습니다.
교차 타입은 서로 다른 타입을 결합하여 새로운 타입을 만든것 입니다.

type Circle = {
  radius: number;
};

type Colorful = {
  color: string;
};

// &를 사용해 결합하여 새로운 타입 생성
type ColorfulCircle = Circle & Colorful;

const happyFace: ColorfulCircle = {
  radius: 4,
  color: "yellow",
};
type Cat = {
  numLives: number;
};

type Dog = {
  breed: string;
};

// &를 사용해 결합하여 새로운 타입 생성
type CatDog = Cat &
Dog & {
  age: number;
};

const christy: CatDog = {
  numLives: 7,
  breed: "Mixed",
  age: 9,
};





Index Signatures


제한된 양의 프로퍼티 또는 키를 가지는 타입을 정의해 주는 방법입니다.
key 타입은 string, number, symbol, Template literal을 사용할 수 있습니다.


키의 타입이 string 일 때

type Words = {
    [key:string]: string
}

let dict: Words = {
	'potato': 'food'
}

키의 타입이 number 일 때

type Words = {
    [key:number]: string
}

// Type '{ potato: string; }' is not assignable to type 'Words'.
// Object literal may only specify known properties, and '"potato"' does not exist in type 'Words'
let dict: Words = {
	"potato": 'food'
}

키의 타입은 문자열

키의 타입을 string으로 하면 어차피 문자 타입으로 변환되기 때문에 number, boolean, null, undefined... 타입을 키로 사용하여도 타입스크립트 경고는 발생하지 않습니다.
(심볼 제외)

type Words = {
    [key: string]: string
}

let dict: Words = {
	1: 'one'
}

let dict2: Words = {
	true: 'false'
}

let dict3: Words = {
	null: 'no'
}

let dict4: Words = {
	undefined: 'defined'
}


console.log(dict["1"])
// "one"

console.log(dict["true"])
// "false"

console.log(dict3["null"])
// "no"

console.log(dict["undefined"])
// "defined"

자바스크립트에서 키의 타입은 주로 문자열과 심볼이지만, 다른 타입의 값을 객체의 키로 사용하려고 하면 JavaScript에서 자동으로 해당 값이 문자열로 변환됩니다. 예를 들어, 숫자나 불리언 값을 객체의 키로 사용하면 자동으로 문자열로 변환됩니다.

0개의 댓글