ts에서 기본적으로 제공하는 타입선언이 모여있는 파일임.
확장자가 d.ts인 이유? => 실제로 실행되는 코드는 없고 자바스크립트의 ㅌ아ㅣㅂ 선언만 들어가있음.(실제 구현은 JS에서 함)
배열은 모든 파일에 인터페이스로 선언되어 있어 자동적으로 병합됨.
{
type Result = Partial<{a:string, b:string}>
type MyPartial<T> ={
[P in keyof T]? : T[P];
}
type Result2 = MyPartial<{a:string, b:string}>
}
모든 속성을 optional이 아니게 만들어줌
앞에 readonly 키워드를 사용하면 모든 속성을 readonly로 만들어줌
-readonly로 적으면 => 모든 속성을 readonly 가 아니가 만들어줌
type MyRequired<T> = {
(readonly) [P in keyof T]-? : T[P];
} // -는 반대라는 의미
type Result3 = MyRequired<{a?:string, b?:string}>
객체를 as const로 정의를 해주게 되면 객체내의 모든 타입 속성들이 readonly로 바뀌는 것을 확인할 수 있다.
만약 일부의 타입 속성들만 상수로써 바뀌지 않게 하고 싶다면 해당 타입 속성의 변수명의 앞에 readonly를 붙여주도록 한다.
객체 자체를 상수처럼 쓰려면 as const, 속성 일부를 읽기전용으로 만드려면 readonly
const numbers1 = [1, 2]; // number[]
const numbers2 = [1, 2] as const; // readonly [1,2]
const plus = (a: number, b: number) => {
return a + b;
}
console.log(plus(...numbers1)); // error
console.log(plus(...numbers2)); // fine
class A {
obj1 = { property: 123 } as const;
// A.obj1: { readonly propery: 123 };
readonly obj2 = { property: 123 };
// A.obj2: { propery: number };
readonly obj3 = { property: 123 } as const;
// A.obj3: { readonly propery: 123 };
setObj() {
this.obj1 = { property: 123 }; // fine
this.obj2 = { property: 123 }; // error
this.obj3 = { property: 123 }; // error
}
setObjPropery() {
this.obj1.property = 123; // error
this.obj2.property = 123; // fine
this.obj3.property = 123; // error
}
}
객체에서 지정한 속성만 가져오는 utility types
지정한 속성을 포함한 객체 type을 반환함
T는 key중의 하나여아하므로, extends로 제약조건을 걸었음. => key값이 아닌게 들어오면 error발생
속성에서 P값을 직접 extends하는 방법으로 이를 해결가능
type Result = Pick<{a:string, b:string},'a'>
type MyPick<T, K extends keyof T> = {
[P in K] : T[P];
}
type Result2 = MyPick<{a:string, b:string, c:number},'a'|'c'|'d'> //error : d는 프로퍼티가아님
type MyPick2<T, K> = {
[P in K extends keyof T] : T[P];
}
type Result3 = MyPick2<{a:string, b:string, c:number},'a'|'c'|'d'>
//프로퍼티가 아닌값도 알아서걸러줌.
// <K, T> 형태로 선언해서 사용함.
type Result4 = Record<"a"|"b", string>
어떤 타입에서 지정한 타입을 제거함.
1|"2"|3 은 union type이므로 분배법칙이 실행됨. => 그래서 result가 number만 남게 되는 형태임.
type Result = Exclude<1|"2"|3, string>;
type Result3 = Omit<A, "a"|"c">
type Result2 = Extract<A, string> //객체 type에는 사용 불가능함. never
Pick Type과 반대 => 특정 객체에서 지저안 속성 제거함.
유니언을 만나면 분배법칙이 실행됨.
type Result3 = Omit<A, "a"|"c">
타입에서 null과 undefined를 제거
객체에서 null, undefined를 제거하면 => keyof 연산자 + 인덱스 시그니처를 활용하면 됨.
type Result4 = NonNullable<string|null|number|undefined>
type MyObject = {
name: string | null;
age: number | undefined;
city: string;
};
type CleanedObject = {
[K in keyof MyObject]: NonNullable<MyObject[K]>;
};
일부 속성만 optional로 만드는 type(공식 utility type아님)
먼저 Pick으로 객체에서 지정된 속성만 가져온뒤 이를 Partial로 만듬(일부 optional)
다음 omit으로 지정된 속성을 제외한 type을 가져옴
이 둘을 intersection함.
type Optional<T, K extends keyof T> = Omit <T,K> & Partial<Pick<T,K>>
type Result1 = Optional<{a:'hi', b:123}, 'a'>;
//
const obj : Result1 ={
b:123
}
함수에서 파라미터, return
생성자함수에서 파라미터, 인스턴스 type 뽑아냄
abstract new 키워드를 사용한 이유 => 추상클래스까지 포함하려고 사용함.
type Parameters<T extends (...args:any) => any> = T extends (...args : infer P) => any ? P : never;
type MyConstructorParameters<T extends abstract new (...args:any) => any> = T extends abstract new (...args : infer P) => any ? P : never;
type ReturnType<T extends (...args:any) => any> = T extends (...args : any) => infer R? R : any;
type InstanceType<T extends abstract new (...args:any) => any> = T extends abstract new (...args : any) => infer P ? P : any;
메서드들에 this를 한번에 주입하는 type임
이런식으로 모든 형태를 정의할 수도 있지만, 코드 중복이 발생함.
이럴때 this를 명시적으로 binding해주는 type
type Data = {
money : number
};
type Methods= {
addMoney(this : Data& Methods, amount : number) => void;
useMoney(this : Data& Methods, amount : number) => void;
}
type Obj = {
data : Data,
method : Methods
}
const obj:Obj = {
data: {
money : 0,
},
method : {
addMoney(amount:number){
this.money += amount;
},
useMoney(amount:number){
this.money += amount;
},
}
}
// 이렇게도 작성가능
type Methods= {
addMoney(amount : number) => void;
useMoney(amount : number) => void;
}
type Obj = {
data : Data,
method : Methods & ThisType<Data & Methods>;
}
ref) https://velog.io/@pudding/typescriptconst-as-const-readonly