Lsiron
Type Script 의 Object 심화 (index signature, recursive, keyof, 타입변환기) 본문
Type Script 의 Object 심화 (index signature, recursive, keyof, 타입변환기)
Lsiron 2024. 7. 18. 16:42index signature
Index Signature 는 객체의 속성 키가 동적으로 정의될 수 있는 경우 유용하다.
Index Signature 는 객체의 속성 이름이 특정 타입이고, 그 속성의 값이 다른 특정 타입임을 지정한다.
이는 객체가 동적 프로퍼티를 가질 때, 예를 들어 동적으로 추가되는 속성의 타입을 정의하고 싶을 때 매우 유용하다.
즉, 객체의 속성이 여러개 일 때, 한번에 타입을 지정 할 수 있는 방법이 바로 index signature를 사용하는 방법이다.
기본사용
interface StringNumberDictionary {
[key: string]: number;
}
const scores: StringNumberDictionary = {
alice: 10,
bob: 15,
charlie: 20
};
console.log(scores.alice); // 10
console.log(scores["bob"]); // 15
위 예시처럼 alice, bob, charlie 속성에 각각 타입을 지정하지 않아도 index signature 를 통해 한번에 속성의 타입을 number로 지정할 수 있다.
인덱스 시그니처와 다른 프로퍼티의 혼합 사용
인덱스 시그니처를 사용하면서 고정된 프로퍼티를 함께 사용할 수 있다.
이 경우, 고정된 프로퍼티의 타입은 인덱스 시그니처의 타입과 호환되어야 한다.
즉, 고정된 프로퍼티 타입과 인덱스 시그니처의 타입이 적어도 한 개는 일치해야 한다는 것 이다.
interface StringNumberDictionary {
[key: string]: number;
length: number; // 고정된 프로퍼티
}
const data: StringNumberDictionary = {
length: 2,
a: 1,
b: 2
};
숫자 키를 사용하는 인덱스 시그니처 ( 속성이름이 숫자 인 경우 )
숫자 키를 사용하는 인덱스 시그니처를 정의할 수도 있다.
interface NumberArray {
[index: number]: string; // key:number, key:string도 가능하다.
}
const myArray: NumberArray = ["Hello", "World"];
console.log(myArray[0]); // "Hello"
console.log(myArray[1]); // "World"
문자열과 숫자 인덱스의 혼합 사용
숫자 인덱스 시그니처를 사용하면 TypeScript는 문자열 인덱스도 해당 타입으로 간주한다.
이는 자바스크립트 객체의 속성이 항상 문자열로 변환되는 점을 반영한다.
interface AnotherType {
[index: number]: string;
[key: string]: string | number;
}
const example: AnotherType = {
0: "Zero",
1: "One",
name: "Example",
length: 2
};
console.log(example[0]); // "Zero"
console.log(example["name"]); // "Example"
인덱스 시그니처를 사용할 때 주의할 점은, 모든 고정된 프로퍼티의 타입이 인덱스 시그니처의 타입과 호환되어야 한다는 것이다.
예를 들어, 아래와 같은 코드는 오류를 발생시킨다.
interface InvalidExample {
[key: string]: number;
name: string; // 오류: 'name' 속성은 'number' 타입이어야 함
}
recursive 타입지정?
Recursion는 어떤 함수나 타입이 자기 자신을 참조하여 정의되는 것을 말한다. 즉, 재귀적 용법이라는 뜻인데,
recursive 타입지정이란, 재귀적으로 타입을 지정 해 주는 것이다.
TypeScript에서 재귀적으로 타입을 지정하는 방법은 타입 정의 안에서 자기 자신을 참조하는 형태로 이루어진다.
주로 트리 구조나 중첩된 객체 구조를 표현할 때 사용된다.
interface MyType {
'font-size' : MyType | number
}
let css :MyType = {
'font-size' : {
'font-size' : {
'font-size' : 14
}
}
}
속성 값에 타입명을 다시 넣어줌으로써 재귀적으로 타입을 지정 해 줄 수 있다.
내부에 중첩해서 코드를 만들 일이 있을 때 사용해보자.
트리 구조
트리, 그래프, 계층적 데이터 구조를 표현할 때 사용한다.
interface TreeNode {
value: number;
children?: TreeNode[]; // TreeNode 타입의 배열을 가질 수 있음
}
const tree: TreeNode = {
value: 1,
children: [
{
value: 2,
children: [
{ value: 4 },
{ value: 5 }
]
},
{
value: 3,
children: [
{ value: 6 },
{ value: 7 }
]
}
]
};
JSON 데이터 구조
중첩된 객체나 배열을 표현할 때 사용한다.
type Json = string | number | boolean | null | Json[] | { [key: string]: Json };
const jsonData: Json = {
name: "Alice",
age: 30,
isStudent: false,
scores: [95, 82, 77],
address: {
city: "Wonderland",
zipCode: "12345"
}
};
허나 사용할 일은 별로 없다.
keyof ?
keyof 연산자는 TypeScript의 유틸리티 타입 중 하나로, 객체 타입의 키(key)를 문자열 리터럴 유니온 타입으로 추출하는 데 사용된다. 이는 주로 객체의 키 타입을 제네릭하게 다룰 때 유용하다.
즉, keyof 연산자는 Object의 모든 키를 추출하는 연산자이다.
interface Person {
name: string;
age: number;
isStudent: boolean;
}
type PersonKeys = keyof Person; // "name" | "age" | "isStudent"
const key1: PersonKeys = "name"; // 유효
const key2: PersonKeys = "age"; // 유효
const key3: PersonKeys = "isStudent"; // 유효
const key4: PersonKeys = "address"; // 오류: 'address'는 'PersonKeys'에 할당될 수 없음
keyof 연산자는 object의 키 들을 이용해서 타입을 체크 할 때 종종 사용한다.
index signature에 keyof를 쓰면 어떻게 될까 ?
interface Person {
[key : string] : number
}
type PersonKeys = keyof Person; // string | number
Object 자료는 숫자를 객체 키에 넣어도 문자로 치환 해 주기 때문에 string | number로 나온다.
타입변환기 ?
TypeScript에서 매핑된 타입(Mapped Types)은 객체 타입의 키를 사용하여 새로운 타입을 생성하는 강력한 도구이다.
매핑된 타입을 사용하면 기존 타입을 변환하여 새로운 타입을 쉽게 정의할 수 있다.
보통 Object의 타입을 바꾸고싶을 때 타입변환기를 만들어서 타입을 변환시켜준다고 한다.
기본 매핑된 타입은 객체 타입의 모든 키를 순회하며 각 키에 대해 새로운 타입을 정의한다.
이는 in 연산자외 위에서 배운 keyof 연산자를 사용하여 구현된다.
type Person = {
name : string,
age : number,
isStudent : boolean
}
type TypeChanger<T> = {
[K in keyof T] : string // [자유작명 in keyof 타입파라미터] : 원하는 타입
}
type NewType = TypeChanger<Person>
// NewType은 아래와 같이 변환이 된다.
type NewType = {
name: string;
age: string;
isStudent: string;
}
generic 함수를 사용하여 TypeChanger의 타입 파라미터를 'T' 로 입력 해 주었고, NewType으로 타입을 생성할 때, 인자에 Person 타입을 입력하였다.
이 Person 타입은 'K in keyof T' 의 T에 들어가게 된다.
keyof 연산자를 통해 T에 들어간 Person 타입의 모든 키를 추출하여 리터럴 유니온타입으로 만들어주고,
in 연산자를 통해 왼쪽에 있는 K 값이 오른쪽에 있는 리터럴 유니온타입에 있으면 모두 string으로 바꾸어주라는 뜻이다.
정리하자면 아래와 같다.
1. keyof T : keyof T 는 'name' | 'age' | 'isStudent' 가 된다.
2. K in keyof T : 매핑된 타입에서 사용되는 반복구문이다. K('T' 의 키를 반복적으로 참조하는 임시 변수)는 keyof T로부터 추출된 각 키를 의미하기 때문에, K 는 'name', 'age', 'isStudent' 값을 순차적으로 가진다.
3. 매핑된 타입 생성 : type NewType = { name: string; age: string; isStudent: string;}
참조: 코딩 애플
'언어 > Type Script' 카테고리의 다른 글
Type Script의 데코레이터란? (0) | 2024.07.20 |
---|---|
Type Script 에서 조건문으로 타입만들기, infer (0) | 2024.07.18 |
Type Script 의 implements ? (0) | 2024.07.18 |
Type Script 에서 d.ts 파일이란? 그리고 외부 js 라이브러리 가져오기 (0) | 2024.07.18 |
Type Script 에서 외부 자바스크립트 파일을 사용할 때 (declare, ambient module / local module) (0) | 2024.07.17 |