typescript 핸드북 학습내용 정리
https://typescript-kr.github.io/pages/the-handbook.html
인터페이스
첫 번째 인터페이스 (Our First Interface)
interface LabeledValue {
label: string;
}
function printLabel(labeledObj: LabeledValue) {
console.log(labeledObj.label);
}
let myObj = {size: 10, label: "Size 10 Object"};
printLabel(myObj);
- 타입 검사는 프로퍼티들의 순서를 요구하지 않음.
- 단지 인터페이스가 요구하는 프로퍼티들이 존재하는지와 프로퍼티들이 요구하는 타입을 가졌는지만을 확인.
선택적 프로퍼티 (Optional Properties)
?
interface SquareConfig {
color?: string;
width?: number;
}
읽기전용 프로퍼티 (Readonly properties)
readonly
interface Point {
readonly x: number;
readonly y: number;
}
- 기본적으로 재할당 불가
let a: number[] = [1, 2, 3, 4];
let ro: ReadonlyArray<number> = a;
ro[0] = 12; // 오류!
ro.push(5); // 오류!
ro.length = 100; // 오류!
a = ro; // 오류!
a = ro as number[]; // 타입 단언으로 오버라이드는 가능
- 변수는 const를 사용하고 프로퍼티는 readonly를 사용하자.
초과 프로퍼티 검사 (Excess Property Checks)
객체 리터럴이 "대상 타입 (target type)"이 갖고 있지 않은 프로퍼티를 갖고 있으면, 에러가 발생함.
// error: Object literal may only specify known properties, but 'colour' does not exist in type 'SquareConfig'. Did you mean to write 'color'?
let mySquare = createSquare({ colour: "red", width: 100 });
- 피하는 방법 1 - 타입 단언
let mySquare = createSquare({ width: 100, opacity: 0.5 } as SquareConfig);
- 피하는 방법 2 - 문자열 인덱스 서명 추가
interface SquareConfig {
color?: string;
width?: number;
[propName: string]: any;
}
- 피하는 방법 3 - 다른 변수에 할당
let squareOptions = { colour: "red", width: 100 };
let mySquare = createSquare(squareOptions);
//squareOptions와 SquareConfig 사이에 공통 프로퍼티가 있는 경우에만 위와 같은 방법을 사용할 수 있음
초과 프로퍼티 에러의 대부분은 실제 버그. 왠만하면 피하지 말자
함수 타입 (Function Types)
interface SearchFunc {
(source: string, subString: string): boolean;
}
// 매개변수의 이름이 같을 필요는 없음
let mySearch: SearchFunc;
mySearch = function(src: string, sub: string): boolean {
let result = src.search(sub);
return result > -1;
}
인덱서블 타입 (Indexable Types)
a[10] 이나 ageMap[“daniel”] 처럼 타입을 “인덱스로” 기술할 수 있음.
// StringArray가 number로 색인화(indexed)되면 string을 반환
interface StringArray {
[index: number]: string;
}
let myArray: StringArray;
myArray = ["Bob", "Fred"];
let myStr: string = myArray[0];
- 인덱스 서명을 지원하는 타입 👉 문자열과 숫자.
- 두 타입의 인덱서(indexer)를 모두 지원하는 것은 가능하지만, 숫자 인덱서에서 반환된 타입은 반드시 문자열 인덱서에서 반환된 타입의 하위 타입(subtype)이어야 합니다.
이 이유는 number로 인덱싱 할 때, JavaScript는 실제로 객체를 인덱싱하기 전에 string으로 변환하기 때문.
즉, 100 (number)로 인덱싱하는 것은 “100” (string)로 인덱싱하는 것과 같기 때문에, 서로 일관성 있어야 합니다.
interface Foo{
name: number; //오류발생 "number 는 string 에 할당이 불가능합니다" (서브타입 x)
[index :string]:string
}
문자열 인덱스 시그니처는 “사전” 패턴을 기술하는데 강력한 방법이지만, 모든 프로퍼티들이 반환 타입과 일치하도록 강제함. 문자열 인덱스가 obj.property가 obj[“property”]로도 이용 가능함을 알려주기 때문.
interface NumberDictionary {
[index: string]: number;
length: number; // 성공, length는 숫자입니다
name: string; // 오류, `name`의 타입은 인덱서의 하위타입이 아닙니다
}
인덱스 시그니처가 프로퍼티 타입들의 합집합이라면 다른 타입의 프로퍼티들도 허용할 수 있음
interface NumberOrStringDictionary {
[index: string]: number | string;
length: number; // 성공, length는 숫자입니다
name: string; // 성공, name은 문자열입니다
}
읽기 전용
interface ReadonlyStringArray {
readonly [index: number]: string;
}
let myArray: ReadonlyStringArray = ["Alice", "Bob"];
myArray[2] = "Mallory"; // 오류!
인터페이스 확장하기 (Extending Interfaces)
interface Shape {
color: string;
}
interface Square extends Shape {
sideLength: number;
}
let square = {} as Square;
square.color = "blue";
square.sideLength = 10;
interface Shape {
color: string;
}
interface PenStroke {
penWidth: number;
}
interface Square extends Shape, PenStroke {
sideLength: number;
}
let square = {} as Square;
square.color = "blue";
square.sideLength = 10;
square.penWidth = 5.0;
하이브리드 타입 (Hybrid Types)
ex) 함수와 객체 역할 모두 수행하는 객체
interface Counter {
(start: number): string;
interval: number;
reset(): void;
}
function getCounter(): Counter {
let counter = (function (start: number) { }) as Counter;
counter.interval = 123;
counter.reset = function () { };
return counter;
}
let c = getCounter();
c(10);
c.reset();
c.interval = 5.0;
써드파티 (3rd-party) JavaScript와 상호작용할 때, 타입의 형태를 완전히 기술하기 위해 위와 같은 패턴을 사용해야할 수도 있습니다.
'공부공부 > TS' 카테고리의 다른 글
| [typescript 핸드북] 06. 열거형 (0) | 2024.02.19 |
|---|---|
| [typescript 핸드북] 05. 유니언과 교차 타입 (0) | 2024.02.19 |
| [typescript 핸드북] 04. 리터럴 타입 (0) | 2024.02.19 |
| [typescript 핸드북] 03. 함수 (0) | 2024.02.19 |
| [typescript 핸드북] 01. 기본타입 (0) | 2024.02.19 |