Skip to content

Latest commit

 

History

History
124 lines (115 loc) · 3.83 KB

File metadata and controls

124 lines (115 loc) · 3.83 KB

Home > types-kit > SetRequiredDeep

SetRequiredDeep type

Make some properties (includes deep properties) in T required.

Signature:

export type SetRequiredDeep<T, K extends DeepKeys<T>> = IsNever<
  Extract<K, Keys<T>>
> extends true
  ? // for tuple when not match the first level properties
    {
      [P in keyof T]: T[P] extends infer V
        ? V extends V
          ? IsObject<V> extends true
            ? SetRequiredDeep<
                V,
                // distributed condition type
                K extends `${infer Head}.${infer Tail}`
                  ? P extends Head
                    ? Extract<
                        Tail extends Tail
                          ? `${P}.${Tail}` extends K
                            ? Tail
                            : never
                          : never,
                        DeepKeys<V>
                      >
                    : never
                  : never
              >
            : V
          : never
        : never
    }
  : Simplify<
      {
        [P in keyof T as If<
          And<[IsExtends<P, Keys<T>>, IsExtends<P, K>]>,
          P,
          never
        >]-?: T[P] extends infer V
          ? V extends V
            ? IsObject<V> extends true
              ? SetRequiredDeep<
                  V,
                  // distributed condition type
                  K extends `${infer Head}.${infer Tail}`
                    ? P extends Head
                      ? Extract<
                          Tail extends Tail
                            ? `${P}.${Tail}` extends K
                              ? Tail
                              : never
                            : never,
                          DeepKeys<V>
                        >
                      : never
                    : never
                >
              : V
            : never
          : never
      } & {
        [P in keyof T as If<
          And<[IsExtends<P, Keys<T>>, Not<IsExtends<P, K>>]>,
          P,
          never
        >]: T[P] extends infer V
          ? V extends V
            ? IsObject<V> extends true
              ? SetRequiredDeep<
                  V,
                  // distributed condition type
                  K extends `${infer Head}.${infer Tail}`
                    ? P extends Head
                      ? Extract<
                          Tail extends Tail
                            ? `${P}.${Tail}` extends K
                              ? Tail
                              : never
                            : never,
                          DeepKeys<V>
                        >
                      : never
                    : never
                >
              : V
            : never
          : never
      }
    >

References: DeepKeys, IsNever, Keys, IsObject, SetRequiredDeep, Simplify, If, And, IsExtends, Not

Example

interface Props {
       a?: {
         b?: number | undefined
         readonly c?: {
           d?: number
         }
       }
       e?: number
     }
     // Expect: {
     //    a: {
     //     b: number | undefined
     //     readonly c?: {
     //        d: number
     //     }
     //   }
     //    e: number
     // }
     type NewProps = SetRequiredDeep<Props, 'e' | 'a' | 'a.b' | 'a.c.d'>