Skip to main content

leveraging-partial-types-readonly-and-pick

Leveraging Partial Types, Readonly, and Pick:

  1. Use of Partial Types:

    interface User {
    id: number;
    name: string;
    email: string;
    }

    function updateUser(id: number, updates: Partial<User>) {
    // Function to update a user with only the fields provided in updates.
    }
  2. Creating Update Patterns with Partial:

    function applyPatch<T>(object: T, patch: Partial<T>): T {
    return { ...object, ...patch };
    }

    // Usage:
    const originalUser = { id: 1, name: 'John', email: 'john@example.com' };
    const updatedUser = applyPatch(originalUser, { email: 'john.doe@example.com' });
  3. Readonly for Immutability:

    interface ImmutableUser {
    readonly id: number;
    readonly name: string;
    readonly email: string;
    }

    const user: ImmutableUser = { id: 1, name: 'Jane', email: 'jane@example.com' };
    // user.name = 'John'; // Error: Cannot assign to 'name' because it is a read-only property.
  4. Protecting State with Readonly:

    function freezeUser(user: Readonly<User>) {
    // Now user's properties cannot be altered.
    }

    // Usage:
    freezeUser({ id: 2, name: 'Doe', email: 'doe@example.com' });
  5. Mapping Types to Readonly:

    type ReadonlyUser = Readonly<User>;

    // Usage:
    let readOnlyUser: ReadonlyUser = { id: 3, name: 'Smith', email: 'smith@example.com' };
    // readOnlyUser.id = 4; // Error: Cannot assign to 'id' because it is a read-only property.
  6. Pick for Selecting Properties:

    type UserEmail = Pick<User, 'email'>;

    // Usage:
    const userEmail: UserEmail = { email: 'selective@example.com' };
    // userEmail.id; // Error: Property 'id' does not exist on type 'UserEmail'.
  7. Creating Subtypes with Pick:

    type UserInfo = Pick<User, 'id' | 'name'>;

    function displayUserInfo(userInfo: UserInfo) {
    // Function to display user information without exposing the email.
    }

    // Usage:
    displayUserInfo({ id: 4, name: 'Alex' });
    1. Combining Partial with Readonly:
    type PartialReadonlyUser = Partial<Readonly<User>>;

    // Usage:
    const newUser: PartialReadonlyUser = { name: 'New Name' }; // Only 'name' is set, rest are optional.
    // newUser.name = 'Another Name'; // Error: Cannot assign to 'name' because it is a read-only property.
  8. TypeScript's Structural Typing with Partial and Pick:

    // Assume User type from previous example.
    type PartialName = Partial<Pick<User, 'name'>>;

    // Usage:
    const userWithPartialName: PartialName = { name: 'Optional Name' }; // 'name' is optional, other User properties are not present.
  9. Utility Types in APIs:

    function updateUserData(userId: number, updates: Partial<User>): Readonly<User> {
    // Function that updates user and returns a Readonly version of User.
    // Implementation here...
    return {} as Readonly<User>;
    }
  10. Refactoring with Readonly and Pick:

    type ReadonlyUserInfo = Readonly<Pick<User, 'id' | 'name'>>;

    function getUserInfo(userId: number): ReadonlyUserInfo {
    // Refactored function that returns only the id and name, both as readonly.
    // Implementation here...
    return {} as ReadonlyUserInfo;
    }
  11. Nested Partial Types:

    interface NestedUser {
    id: number;
    profile: {
    name: string;
    address: {
    street: string;
    city: string;
    };
    };
    }

    type PartialNestedUser = Partial<{
    [P in keyof NestedUser]: Partial<NestedUser[P]>
    }>;

    // Usage:
    const partialNestedUser: PartialNestedUser = { profile: { address: { city: 'City Name' } } };
  12. Leveraging Utility Types for Function Signatures:

    function processUser(user: Readonly<Pick<User, 'id' | 'name'>>): Partial<User> {
    // Process the user and possibly return partial updates.
    // Implementation here...
    return { email: 'newemail@example.com' };
    }
  13. Extendability with Utility Types:

    type CustomUserType = Readonly<Partial<Pick<User, 'name' | 'email'>>>;

    // Usage:
    const customUser: CustomUserType = { name: 'Custom Name' }; // 'email' is optional, 'id' is not included.
  14. Advanced Mapped Types with Readonly and Pick:

    type AdvancedMappedType<T> = {
    [P in keyof T as P extends 'sensitive' ? never : P]: Readonly<Pick<T, P>>
    };

    interface UserWithSensitiveData {
    id: number;
    name: string;
    sensitive: {
    ssn: string;
    password: string;
    };
    }

    type SafeUser = AdvancedMappedType<UserWithSensitiveData>;

    // Usage:
    const safeUser: SafeUser = {
    id: 1,
    name: 'John Doe',
    // 'sensitive' property is omitted due to conditional mapped type.
    };