泛型条件
T extends U? X: Y
T extends U? T: never
枚举转联合类型
enum StringEnum {
Small = 'S',
Medium = 'M',
Large = 'L',
}
type ValuesUnion = `${StringEnum}`;
type KeysUnion = keyof typeof StringEnum;
对象属性操作
type TestBookType = { width: number; height: number; text?: string; color: 'red' | 'blue' };
type PartialOption<T, U extends keyof T> = Partial<Pick<T, U>> & Omit<T, U>;
const book_1: PartialOption<TestBookType, 'color'> = { width: 50, height: 100 };
const newBook: PartialOption<TestBookType, 'color'> & { textColor?: 'red' | 'blue' } = book_1;
newBook['textColor'] = newBook['color'];
delete newBook['color'];
type PartialRequired<T, U extends keyof T> = Required<Pick<T, U>> & Omit<T, U>;
const book_2: PartialRequired<TestBookType, 'text'> = {
width: 50,
height: 100,
text: 'book',
color: 'blue',
};
type PartialTransform<T, U, N> = { [P in keyof T]: T[P] extends U ? N : T[P] };
const book_3: PartialTransform<TestBookType, 'red' | 'blue', 'white'> = {
width: 50,
height: 100,
text: 'book',
color: 'white',
};
类型推断
数组
type InferArray<T> = T extends (infer U)[] ? U : never;
type Pop<T extends any[]> = T extends [...infer L, infer R] ? [...L] : [];
type Shift<T extends any[]> = T extends [infer L, ...infer R] ? [...R] : [];
type ArrayTest = Shift<['ddd', 123]>;
const test: ArrayTest = [123];
对象属性名
type InferRecordKey<T> = T extends Record<infer R, unknown> ? R : never;
type testRecordType = Record<'a' | 'b' | 'c', number>;
type RecordKeyType = InferRecordKey<testRecordType>;
const recordKey: ObjectTest = 'a';
函数返回值
type InferReturnType<T extends Function> = T extends (...args: any) => infer R ? R : never;
type testFunctionType = () => number;
type testReturnType = InferReturnType<testFunctionType>;
const testReturn: testReturnType = 1;
type InferSafeReturnType<T> = T extends (...args: any) => infer R ? R : never;
type testReturnType = InferSafeReturnType<testFunctionType>;
const testSafeReturn: testReturnType = 1;
字符串
type InferStringFirst<T extends string> = T extends `${infer First}${infer _}` ? First : never;
type InferStringSecond<T extends string> = T extends `${infer First}${inter Second}${infer _}` ? Second : never;
type testStringFirstType = InferStringFirst<'abc'>
const stringFirst: testStringFirstType = 'a'
type InferStringSecondType = InferStringSecond<'abc'>
const stringFirst: testStringFirstType = 'b'
type TrimLeft<S extends string> = S extends `${infer L}${infer R}`
? L extends ' ' | '\n' | '\t'
? TrimLeft<R>
: S
: '';
type ArrayTest = TrimLeft<' test'>;
const test: ArrayTest = 'test';
联合类型限制分配
type Normal<A, B> = A extends B ? A : false;
type Strict<A, B> = [A] extends [B] ? A : false;
type a = Normal<1 | 2 | 3, 1>;
type a1 = Strict<1 | 2 | 3, 1>;
type RefObj = { value: number };
type b = Normal<{ value: number } | { name: string }, RefObj>;
type b1 = Strict<{ value: number } | { name: string }, RefObj>;
type b2 = Strict<
{ value: number } | { test: string; value: number } | { name: string; value: number },
RefObj
>;