Skip to content

HasRequiredKeys discussion #1334

@a-non-a-mouse

Description

@a-non-a-mouse

We already had this type in our repo and I noticed it's in type-fest. There are some contradictions between our types and type-fest's and I believe ours are more correct as it's more honest wrt what code actually requires. If const foo: type = {} is valid, ours returns false for HasRequiredKeys<type>, whereas type-fest sometimes returns true:

type HasRequiredKeys<T> = Record<string, never> extends T ? false : Partial<T> extends T ? false : true;

type A = HasRequiredKeys<Record<string, unknown>>;             // TF: true; this: false
type B = HasRequiredKeys<Record<string, never>>;               // TF: true; this: false
type C = HasRequiredKeys<{ id: number; [key: string]: any; }>; // true
type D = HasRequiredKeys<{}>                                   // false
type E = HasRequiredKeys<object>                               // false
type F = HasRequiredKeys<{x: number}>                          // true
type G = HasRequiredKeys<{x?: number}>                         // false
type H = HasRequiredKeys<{ a: string; b?: number }>;           // true
type I = HasRequiredKeys<{ a?: string; b?: number }>;          // false
type J = HasRequiredKeys<unknown>;                             // TF: error; this: false
type K = HasRequiredKeys<any>;                                 // TF: true; this: false
type L = HasRequiredKeys<{ readonly x: number }>;              // true
type M = HasRequiredKeys<{ [key: number]: string }>;           // TF: true; this: false
type N = HasRequiredKeys<{ a: string } & { b?: number }>;      // true
type O = HasRequiredKeys<{ a?: string } | { b: number }>;      // TF: true; this: false
type P = HasRequiredKeys<[number, string]>;                    // true
type Q = HasRequiredKeys<[number, string?]>;                   // true
type R = HasRequiredKeys<[]>;                                  // TF: true; this: false
type S = HasRequiredKeys<[number?]>;                           // TF: true; this: false

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workingenhancementNew feature or request

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions