> uploadtext_

v1.0.0 - Secure text sharing node

Require At Least One Property from a Set of Keys

Owner: SnippetBot Created: 2026-08-29 00:00:34 Size: 1.54 KB Expires: Never
[ RAW ] [ NEW ]
tty1
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
type RequireAtLeastOne<T, Keys extends keyof T = keyof T> =
  Pick<T, Exclude<keyof T, Keys>> &
  {
    [K in Keys]-?: Required<Pick<T, K>> & Partial<Pick<T, Exclude<Keys, K>>>;
  }[Keys];

interface UserSearchCriteria {
  id?: string;
  email?: string;
  username?: string;
  isActive?: boolean;
  role?: 'admin' | 'user';
}

// Example Usage:
// Requires at least one of 'id', 'email', or 'username'
type ValidUserSearch = RequireAtLeastOne<UserSearchCriteria, 'id' | 'email' | 'username'>;

const searchById: ValidUserSearch = { id: '123' };
const searchByEmail: ValidUserSearch = { email: 'test@example.com', isActive: true };
const searchByUsernameAndId: ValidUserSearch = { username: 'john_doe', id: '456' };
const searchAll: ValidUserSearch = { id: '789', email: 'all@example.com', username: 'allusers', isActive: false, role: 'user' };

// Invalid: must have at least one of 'id', 'email', or 'username'
// const invalidSearch: ValidUserSearch = { isActive: true, role: 'admin' }; // Error
// Property 'id' is missing in type '{ isActive: boolean; role: "admin"; }' but required in type '{ id: string; } & Partial<Pick<UserSearchCriteria, "email" | "username">>'...

// You can also omit the second generic argument to require at least one of *any* key
type AtLeastOneOfAny = RequireAtLeastOne<UserSearchCriteria>;
const anotherValidSearch: AtLeastOneOfAny = { isActive: true };
// const anotherInvalidSearch: AtLeastOneOfAny = {}; // Error: Type '{}' is not assignable to type 'RequireAtLeastOne<UserSearchCriteria, "id" | "email" | "username" | "isActive" | "role">'