[ts] 조건부 타입
조건부 타입
// T extends U ? X : Y
type IsStringType<T> = T extends string? 'yes': 'no';
type T1 = IsStringType<string>;
// type T1 = "yes"
type T2 = IsStringType<number>;
// type T2 = "no"
type T3 = IsStringType<string | number>;
// type T3 = "yes" | "no"
// 이 경우에는 string | number extends string으로 동작하지 않고(이렇게 동작한다면, type T3 = "no"이다./)
// string extends string, number extends string 각각 동작하게 된다.
type T4 = IsStringType<string> | IsStringType<number>;
// type T4 = "yes" | "no"
type Array2<T> = Array<T>
type T5 = Array2<string | number>;
// type T5 = (string | number)[]
// 이 경우에는 type T5 = string[] | number[]가 아니다.
// 일반적으로는 Union type을 사용하면, type T5 처럼 동작하는 것이 맞는데
type T6 = number | string | never;
// type T6 = string | number
// union type에 never는 없어진다.
type Exclude<T, U> = T extends U? never: T;
type T7 = Exclude<1 | 3 | 5 | 7, 1 | 5 | 9>;
// type t7 = 3 | 7
// 조건부 타입에서 유니온 타입은 각각 동작 한다.
type T8 = Exclude<string | number | (()=> void), Function>;
// type T8 = string | number
type Extract<T, U> = T extends U? T: never;
type T9 = Extract<1 | 3| 5 | 7, 1 | 5| 9>;
// type T9 = 1 | 5
type ReturnType<T> = T extends(...args: any[]) => infer R? R: any;
// T 함수의 반환 타입을 뽑아내준다.
type t1 = ReturnType<() => string>;
// type t1 = string
function f1(s: string): number {
return s.length;
}
type t2 = ReturnType<typeof f1>;
// type t2 = number
type Unpacked<T> = T extends (infer U)[]
? U
: T extends (...args: any[]) => infer U
? U
: T extends Promise<infer U>
? U
: T;
type T11 = Unpacked<string>;
// type T11 = string
type T12 = Unpacked<string[]>;
// type T12 = string
type T13 = Unpacked<()=> string>;
// type T13 = string
type T14 = Unpacked<Promise<string>>;
// type T14 = string
type T15 = Unpacked<Promise<string>[]>;
// type T15 = Promise<string>
type T16 = Unpacked<Unpacked<Promise<string>[]>>;
// type T14 = string[]
type StringPropertyNames<T> = {
[K in keyof T]: T[K] extends string? K : never;
}[keyof T]
interface Person {
name: string;
age: number;
nation: string;
}
// step 1
type StringPropertyNames1<T> = {
[K in keyof T]: T[K] extends string? K : never;
}
type T21 = StringPropertyNames1<Person>;
// type T21 = {
// name: "name";
// age: never;
// nation: "nation";
// }
// step 2
type StringPropertyNames2<T> = {
[K in keyof T]: T[K] extends string? K : never;
}[keyof T]
type T22 = StringPropertyNames2<Person>;
// type T22 = "name" | "nation"
type StringProperties<T> = Pick<T, StringPropertyNames<T>>;
type T23 = StringProperties<Person>;
// type T23 = {
// name: string;
// nation: string;
// }
type Omit<T, U extends keyof T> = Pick<T, Exclude<keyof T, U>>;
interface Person {
name: string;
age: number;
nation: string;
}
type T31 = Omit<Person, 'nation'| 'age'>;
// type T31 = {
// name: string;
// }
type Overwrite<T,U> = {[P in Exclude<keyof T, keyof U>]: T[P]} & U;
interface Person3 {
name: string;
age: number;
}
type T41 = Overwrite<Person, { age: string; nation: string}>;
const p:T41 = {
name: 'pius',
age: '23',
nation: 'korea'
};
#타입스크립트/조건부-타입