EdwardZZZ / articles

工作点滴记录
2 stars 0 forks source link

TS 类型推导 #84

Open EdwardZZZ opened 1 year ago

EdwardZZZ commented 1 year ago

已知枚举类型 A、B,需要限制输入在 A、B 范围之内

enum A {
    A = 'a',
    B = 'b',
}

enum B {
    B = 'b',
    C = 'c',
}

type MergeType<T1, T2> = { [P in keyof T1 | keyof T2]: P extends keyof T1 ? T1[P] : P extends keyof T2 ? T2[P] : never };

type P = MergeType<typeof A, typeof B>;

// 使用 as const
const AB = { ...B, ...A, D: 1 } as const;
type AB = typeof AB[keyof typeof AB];

const a: AB = AB.A;
const d: AB = AB.D;
EdwardZZZ commented 1 year ago

已知类型 A、B,需要根据判断条件推导结果类型是 A 或者 B

type Without<T1, T2> = { [KeyType in Exclude<keyof T1, keyof T2>]?: never };

type MergeExclusive<T1, T2> = (T1 | T2) extends object ? (Without<T1, T2> & T2) | (Without<T2, T1> & T1) : T1 | T2;
EdwardZZZ commented 1 year ago
// type NestedObject = {
//   prop1: {
//     nestedProp1: string;
//     nestedProp2: number;
//   };
//   prop2: string;
// };

// type Subtract<A extends number, B extends number> = 
//   [...Array<A>, ...Array<B>] extends [...Array<infer L>]
//   ? L
//   : never;

// type ExtractKeys<T, Depth extends number = 10> = [Depth] extends [never]
//   ? never
//   : T extends object
//   ? keyof T | {
//       [K in keyof T]: T[K] extends infer U
//         ? U extends object
//           ? ExtractKeys<U, Subtract<Depth, 1>>
//           : never
//         : never;
//     }[keyof T]
//   : never;

// type AllKeys = ExtractKeys<NestedObject>;

// type FlatKeys<T> = T extends object ? (keyof T | FlatKeys<T[keyof T]>) : never;
type FlatKeys<T> = T extends object
    ? { [K in keyof T] : T[K] extends Function ? never : K | FlatKeys<T[K]> }[keyof T]
    : never;

class Test {
    a: number;
    b: string;
    c: C;

    getField(field: FlatKeys<this>) {}
}

class C {
    d: boolean;
    e: string;
}

class T extends Test {
    f: number;
}

const t = new T();
t.getField('');