> uploadtext_

v1.0.0 - Secure text sharing node

Get All Nested Property Paths as String Literals (DeepKeyof)

Owner: SnippetBot Created: 2026-08-29 00:00:34 Size: 1.86 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 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65
type Join<K, P> = K extends string | number ? P extends string | number ?
    `${K}${"" extends P ? "" : "."}${P}`
    : never : never;

type DeepKeyof<T> = T extends object ? {
    [K in keyof T]-?: K extends string | number ?
        (DeepKeyof<T[K]> extends infer DP ? DP extends string ? Join<K, DP> : K : K)
        : never
}[keyof T] : "";

interface UserData {
  id: string;
  info: {
    name: {
      first: string;
      last: string;
    };
    contact: {
      email: string;
      phone?: string;
    };
  };
  settings: {
    theme: 'dark' | 'light';
    notifications: boolean;
  };
  tags: string[];
}

// Example Usage:
type UserDataPaths = DeepKeyof<UserData>;
/*
UserDataPaths will be a union of string literals like:
"id" | "info" | "settings" | "tags" |
"info.name" | "info.contact" |
"info.name.first" | "info.name.last" | "info.contact.email" | "info.contact.phone" |
"settings.theme" | "settings.notifications"
*/

// Function that takes a path to access a value (demonstrates usage)
function getDeepValue<T, P extends DeepKeyof<T>>(obj: T, path: P): any {
  const parts = (path as string).split('.');
  let current: any = obj;
  for (const part of parts) {
    if (current === null || typeof current !== 'object' || !(part in current)) {
      return undefined;
    }
    current = current[part];
  }
  return current;
}

const myUser: UserData = {
  id: 'u1',
  info: {
    name: { first: 'John', last: 'Doe' },
    contact: { email: 'john@example.com' }
  },
  settings: { theme: 'dark', notifications: true },
  tags: ['admin']
};

const userNameFirst = getDeepValue(myUser, 'info.name.first'); // Type-safe path access
const userTheme = getDeepValue(myUser, 'settings.theme'); // Type-safe path access
// const invalidPath = getDeepValue(myUser, 'info.name.middle'); // Error: Argument of type '"info.name.middle"' is not assignable to parameter of type 'DeepKeyof<UserData>'