1_000_234
→ 가독성을 높임class Library {
titles: string[]
constructor() {}
}
const library = new Library()
Library.titles
를 가져다 쓰려고 하면 에러 발생strictPropertyInitialization
옵션 존재strictNullCheck
도 같이 활성화되어 있어야 한다.titles?: string[]
로 변경할 것.titles
가 결정되고 → 컴파일러가 이 사실을 신경쓸 필요가 없다면 → titles!: string[]
로 표현할 것 ( 이 속성은 지금 신경쓰지 않아도 된다. )interface Admin {
id: string;
role: string;
}
interface User {
id: string;
email: string;
}
function redirect(user: Admin | User) {
if (/* 사용자가 어드민이라면 */) {
}
}
function redirect(user: Admin | User) {
if ('role' in user) {
routeToAdminPage(user.role) // 이 부분에서 자동완성 할 때는 `role` 속성밖에 나오지 않음
} else {
routeToHomePage(user.email) // 여기서는 `email` 만 나옴
}
}
role
변수가 존재한다면 내부 로직에서 user 에 대한 타입은 Admin
타입으로 추론된다.interface Pet {
name: string
age: number
}
type ReadonlyPet = { readonly [K in keyof Pet]: Pet[K] }
const pet: Pet = { name: 'Happy', age: 10 }
const readonlyPet: ReadonlyPet = { name: 'Cerberus', age: 1000 }
pet.age = 15
readonlyPet.age = 200 // readonly 속성을 수정하려고 하기 때문에 에러
interface Pet {
name: string
age: number
**favoritePark?: string**
}
type ReadonlyPet = { readonly [K in keyof Pet]**-?**: Pet[K] } // `-?` 부분 주목
// 이제 favoritePark 속성이 없다고 에러가 난다.
const readonlyPet: ReadonlyPet = { name: 'Cerberus', age: 1000 }
Pet
에서는 favoritePark
이 옵셔널 속성이지만 ReadonlyPet
에서는 모든 속성이 필수로 있어야 한다.type
은 같은 파일 안에서 두 번 선언될 수 없다.interface
는 중복 선언될 경우 타입 결합과 동일하게 동작T extends U ? X : Y
type NonNullable<T> = T extends null | undefined ? never : T;
NonNullable
의 타입은 never
가 된다.never
을 활용 → never
타입이 유니언 타입 안에 있으면 자동으로 무시된다.type ArrayOnly<T> = T extends any[] ? T : never
type StringOrNumbers = ArrayOnly<string | number | string[] | number[]>
stringOrNumbers
의 타입은 string[]
OR number[]
interface ItemService {
getItem<T extends string | number>(id: T): T extends string ? Book : Tv
}
let itemService: IItemService
const book = itemService.getItem('10')
const tv = itemService.getItem(10)
const wrong = itemService.getItem(false) // 에러
function generateId(seed: number) { return seed + 5 }
function lookupEntity(id: number) { ... }
lookupEntity(generateId(10)) // success
generateId
함수 리턴 타입은 자동으로 추론이 되어 number
이 된다.generateId
함수의 리턴 값을 lookupEntity
의 인자로 넘겨준다.lookupEntity
의 인자로 타입을 string
으로 바꾸고 싶다면?generateId
함수의 파라미터 타입도 변경해주어야 한다.infer
키워드를 사용할 것."해당 타입을 추론하라" 라고 타입스크립트 엔진에게 시키는 것
typescript 에서 기본으로 제공해주는 ReturnType
타입을 예시로 들어보자
type ReturnType<F> = F extends (...args: any[]) => infer R ? R : any
type UnpackPromiseArray<P> = P extends Promise<infer K>[] ? K : any
const arr = [Promise.resolve(true)]
type ExpectedBoolean = UnpackPromiseArray<typeof arr> // -> boolean
Promise<infer K>[]
라면 K
타입을 리턴한다.infer K
)type NonNullablePropertyKeys<T> = {
[P in keyof T]: null extends T[P] ? never : P
}[keyof T];
type User = {
name: string;
email: string | null;
};
type NonNullableUserPropertyKeys = NonNullablePropertyKeys<User>;
[P in keyof T]
→ name, emailnull extends T[P] ? never : P
null extends string ? never : P
→ Pnull extends string | null ? never : P
→ nevernever
타입 속성을 가진 key는 interface
에서 제거됨T[P]
→ User[P]
type NonNullableUserPropertyKeys = {
[P in keyof User]: null extends User[P] ? never : P
}[keyof User];
keyof User
→ "name" | "email"
type NonNullableUserPropertyKeys = {
[P in "name" | "email"]: null extends User[P] ? never : P
}[keyof User];
unroll Union 타입
type NonNullableUserPropertyKeys = {
name: null extends User["name"] ? never : "name";
email: null extends User["email"] ? never : "email";
}[keyof User];
User Type 내부 키값의 type
type NonNullableUserPropertyKeys = {
name: null extends string ? never : "name";
email: null extends string | null ? never : "email";
}[keyof User];
조건부 타입
type NonNullableUserPropertyKeys = {
name: "name";
email: never;
}[keyof User];
//
type NonNullableUserPropertyKeys = {
name: "name";
email: never;
}["name" | "email"];
name, email 에 대한 타입을 찾기 위한 indexed access를 갖고 있음
각 타입을 개별적으로 조회하면서 해결한다
아래아 유니온타입으로의 결과물
```tsx
type NonNullableUserPropertyKeys =
| { name: "name"; email: never }["name"]
| { name: "name"; email: never }["email"];
```
unroll
type NonNullableUserPropertyKeys =
| "name"
| never;
결과물
```tsx
type NonNullableUserPropertyKeys = "name";
```
- `never` 타입은 제거한다.
출처 - 1
https://rinae.dev/posts/practical-advanced-typescript-summary?fbclid=IwAR0tCClWkoY1zOG0ZiGONE_YlkQztmI03oQpOv2g1JwMVv9ki-PBBQf_FLA#numeric-separator%EB%A5%BC-%EC%82%AC%EC%9A%A9%ED%95%98%EC%97%AC-%ED%81%B0-%EC%88%98%EB%A5%BC-%EB%8B%A4%EB%A3%A8%EA%B8%B0
출처 - 2
https://mariusschulz.com/blog/conditional-types-in-typescript