Closed prefer2 closed 2 years ago
배열의 요소를 읽을 수 있지만, 쓸 수는 없다.
length를 읽을 수 있지만, 바꿀 수 없다.
배열을 변경하는 pop을 비롯한 다른 메서드를 호출 할 수 없다.
number[] 는 readonly number[] 보다 기능이 많기 때문에, readonly number[] 의 서브타입이 된다.
따라서 변경 가능한 배열을 readonly 배열에 할당 가능하다. (하지만 그 반대는 불가능!)
readonly string[][]; // 1번
(readonly string[])[]; //2번
1번 : 변경 가능한 배열의 readonly 배열
2번 : readonly 배열의 변경 가능한 배열
Readonly 제네릭도 얕게 동작한다.
why
why
type Rocket = { [property: string] : sring };
const rocket: Rocket {
name: 'Falcon 9;,
variant: 'v1.0',
thrust: '43390 kN'
}
단점
인덱스 시그니처는 동적 데이터를 표현할 때 사용한다.
어떤 타입에 가능한 필드가 제한되어 있는 경우에는 인덱스 시그니처를 사용하지 말아야 한다.
interface Row1 { [column: string]: number } // 너무 광범위하다
// Record 사용
type Vec3D = Record<'x' | 'y' | 'z', number>;
// 매핑된 타입 사용
type Vec3D_v2 = {[k in 'x' | 'y' | 'z']: number};
type ABC = {[k in 'a' | 'b' | 'c']: k extends 'b' ? string : number};
Record
는 키 타입에 유연성을 제공하는 제너릭 타입이다.
매핑된 타입을 통해서도 모델링 가능. 키마다 별도의 타입을 사용할 수 있다.
그럼 언제 인덱스 시그니처를 사용할까? → 런타임 때까지 객체의 속성을 알 수 없을 때. 단 안전한 접근을 위해 인덱스 시그니처의 값 타입에 undefined를 추가하는 것을 고려해야 한다.
자바스크립트에서 배열은 객체이다. 객체에서 숫자는 키로 사용할 수 없다. 키로 숫자를 사용하고자 하면 자바스크립트 런타임은 이를 문자열로 변환한다. Object.keys를 이용해 배열의 키를 나열해 보면, 키가 문자열로 출력된다.
타입스크립트는 혼란을 바로잡기 위해 객체에서 숫자 키를 혀용하고, 문자열 키와 다른 것으로 인식한다. 다만 이는 타입스크립트에서만 일어나는 일이고 실제 런타임에 사용되는 키는 string 타입이다.
readonly 접근 제어자
number[]는 readonly number[]보다 기능이 많다. 즉 readonly number[]의 서브타입이다. 따라서 변경 가능한 배열을 readonly 배열에 할당할 수 있다. 하지만 그 반대는 불가능하다.
매개변수를 readonly로 선언하면
readonly를 붙이는 명시적인 방법을 사용하는 것이 컴파일러와 사람 모두에게 좋다.
어떤 핫무를 readonly로 만들면, 그 함수를 호출하는 다른 함수도 모두 readonly로 만들어야 한다. 라이브러리에 있는 함수를 호출한다면 타입 선언을 바꾸지 못하므로 타입 단언문을 사용해야 한다.
const dates: readonly Date[] = [new Date()];
dates.push(new Date()); // push 형식이 없습니다
dates[0].setFullYear(2037); // 정상
인터페이스 선언과 타입 선언의 비슷한 점
인덱스 시그니처를 모두 사용 할 수 있다
type TDict = { [key:string] : string};
interface IDict {
[key: string] : string;
}
함수 타입으로 정의할 수 있다
const toStrT : TFn = x => '' + x;
interface IFn {
(x:number) : string;
}
제너릭이 가능하다
type TPair<T> = {
first: T;
second: T;
}
interface IPair<T>{
first: T;
second: T;
}
클래스를 구현할 때에 둘 다 사용이 가능하다
인터페이스 선언과 타입선언의 차이
인터페이스는 타입 확장이 가능하다
유니온 인터페이스는 없다
type 은 매핑된 타입 또는 조건부 타입과 같은 고급 기능에 활용이 가능하다
튜플과 배열 타입을 type을 활용하여 간결하게 표현할 수 있다
type Pair = [number, number];
인터페이스는 보강이 가능하다
인터페이스와 타입 중 어떤 것을 사용해야할까?
타입 중복
반복을 줄이는 방법
타입에 이름을 붙이기
타입의 일부분을 표현하는 경우, 인덱싱을 통해서 중복 제거가 가능
interface State {
userId : string;
pageTitle: string;
recentFiles: string[];
pageContents: string;
}
interface TopNavState {
userId: State['userId'];
pageTitle: State['pageTitle'];
recentFiles: State['recentFiles'];
}
맵핑된 타입을 사용하기
type TopNavState = {
[ k in 'userId' | 'pageTitle'| 'recentFiles'] : State(k)
}
type Rocket = { [property: string]: string };
const rocket: Rocket = {
name: 'Falcon 9',
variant: 'v1.0',
thrust: '4,940 kN',
}; // 정상
자바스크립트 객체는 문자열 키를 타입의 값에 관계없이 매핑한다. 타입스크립트에서는 타입에 ‘인덱스 시그니처’를 명시하여 유연하게 매핑을 표현할 수 있다.
위의 [property: string]: string
이 인덱스 시그니처이며, 다음 세 가지 의미를 담는다.
타스 꽤나 재미있는 녀석일지도?