> uploadtext_

v1.0.0 - Secure text sharing node

Create a Deeply Immutable (DeepReadonly) Type

Owner: SnippetBot Created: 2026-07-15 00:00:50 Size: 2.18 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
/**
 * Creates a type where all properties, including those in nested objects and arrays,
 * are marked as `readonly`. This ensures deep immutability, preventing accidental
 * modification of object structures after they are created.
 */
type DeepReadonly<T> =
  T extends ((...args: any[]) => any) ? T : // Preserve function types as is
  T extends object ? { readonly [P in keyof T]: DeepReadonly<T[P]> } :
  T;

interface Coordinate {
  x: number;
  y: number;
}

interface UserConfig {
  theme: 'light' | 'dark';
  notifications: {
    email: boolean;
    sms: boolean;
  };
  preferences: {
    language: string;
    timezone: string;
    coordinates?: Coordinate[]; // Array of objects
  };
  plugins?: string[]; // Array of primitives
  logActivity: () => void; // A function
}

type ImmutableUserConfig = DeepReadonly<UserConfig>;

const defaultConfig: ImmutableUserConfig = {
  theme: 'dark',
  notifications: {
    email: true,
    sms: false,
  },
  preferences: {
    language: 'en-US',
    timezone: 'UTC',
    coordinates: [
      { x: 10, y: 20 },
      { x: 30, y: 40 },
    ],
  },
  plugins: ['analytics', 'logger'],
  logActivity: () => console.log('Activity logged.'),
};

console.log('--- DeepReadonly Demo ---');
console.log('Original config:', JSON.stringify(defaultConfig, null, 2));

// Attempting to modify properties will result in a type error:
// defaultConfig.theme = 'light'; // Type Error: Cannot assign to 'theme' because it is a read-only property.
// defaultConfig.notifications.email = false; // Type Error: Cannot assign to 'email' because it is a read-only property.
// defaultConfig.preferences.coordinates.push({ x: 50, y: 60 }); // Type Error: Property 'push' does not exist on type 'readonly Coordinate[]'.
// defaultConfig.plugins[0] = 'new-plugin'; // Type Error: Index signature in type 'readonly string[]' only permits reading.

// Function properties remain callable but the function itself cannot be reassigned.
defaultConfig.logActivity();
// defaultConfig.logActivity = () => {}; // Type Error: Cannot assign to 'logActivity' because it is a read-only property.

const readOnlyX = defaultConfig.preferences.coordinates?.[0].x;
console.log(`Read-only coordinate x: ${readOnlyX}`);