Typesaurus Documentation

website·Indexed 31 days ago

https://typesaurus.com

A type-safe wrapper for Firestore that ensures database consistency and provides a seamless API for reading, writing, and real-time updates. Features include first-class support for React and Preact, batch writes, transactions, and advanced schema design tools to secure Firestore databases with full type safety.

Tokens
28.9K
Snippets
188
Records
212
Agent score
56%

What's inside Typesaurus

  1. Ensure Firestore data consistency with Typesaurus type-safety

    Typesaurus provides type-safety for Firestore databases to ensure 100% data consistency. It achieves this by treating document IDs as distinct types, preventing the accidental mixing of different ID types (e.g., preventing a user ID from being used where an account ID is expected). Additionally, Typesaurus validates writes at the type-level to prevent documents from entering inconsistent states.
  2. Implement type-safety and typed IDs in Firestore

    Typesaurus enhances Firestore's schema-less nature by providing advanced type-safety that accounts for Firestore-specific nuances (such as server dates and the conversion of undefined to null). Additionally, it implements typed document IDs to prevent bugs and provide self-documenting static or shared IDs.
  3. Use SubscriptionPromise to read documents or subscribe to updates

    The SubscriptionPromise class is returned by all reading operations. It implements the Promise interface, allowing it to be used with await, .then(), or .catch(). It supports two mutually exclusive modes: Promise mode (one-time read) and Subscription mode (real-time updates).
    // Initialize the operation (no request is sent to the DB yet)
    const sp = db.users.get(userId);
    
    // Option 1: Read document once
    const doc = await sp;
    
    // Option 2: Subscribe to updates
    sp.on((doc) => {
      console.log('Document updated:', doc);
    });
  4. Use the Doc class to manage database documents

    The Doc class represents a document in the database and is returned from reading operations or created via a collection. It serves as a wrapper that provides access to both the document's reference (metadata/ID) and its actual data, along with methods for reading and writing.
    import { schema } from "typesaurus";
    const db = schema({
      users: collection<User>("users"),
      posts: collection<Post>("posts"),
    });
    
    // Retrieve a Doc instance
    const doc = await db.users.get(db.users.id("00sHm46UWKObv2W7XK9e")); // => Doc<User>
    
    // Access the ID via the ref property
    console.log(doc.ref.id); // => "00sHm46UWKObv2W7XK9e"
    
    // Access the document data
    console.log(doc.data); // => User
  5. Implement type-safe IDs for database collections

    Typesaurus ensures that IDs are typed based on their collection path to prevent bugs caused by mixing IDs from different entities (e.g., using an account ID where a user ID is expected). By default, a collection ID is linked to its path. For example, a user collection ID is typed as Id<"users"> and a subcollection ID is typed as Id<"users/reports">.
    import { schema } from "typesaurus";
    const db = schema(($) => ({
      users: $.collection<User>(),
      accounts: $.collection<Account>().sub({
        reports: $.collection<Report>(),
      }),
    }));
    
    // TypeScript will prevent this:
    db.users.update(accountId, { name: "Sasha" }); 
    // Error: Argument of type 'Id<"accounts">' is not assignable to parameter of type 'Id<"users">'.
  6. Handle undefined values in Typesaurus models

    Because Firestore does not support undefined values and throws runtime errors when they are encountered, Typesaurus automatically replaces all undefined values with null across both objects and arrays. This ensures consistent behavior and prevents runtime crashes regardless of the TypeScript configuration.

    Since data retrieved from Typesaurus may contain null where the original model defined undefined (or optional properties), you must account for null when consuming the data.

  7. Access and use Collection Groups with the Group class

    The Group class represents a collection group in the database. You access these groups using the groups(db) function. This allows you to target all collections sharing the same name across different paths in your schema.
    interface Comment { text: string; }
    const db = schema(($) => ({
      users: $.collection<User>().sub({
        posts: $.collection<UserPost>().sub({
          comments: $.collection<Comment>(),
        }),
      }),
      posts: $.collection<Post>().sub({
        comments: $.collection<Comment>(),
      }),
    }));
    
    // Accesses all 'comments' collections across the database
    const commentsGroup = groups(db).comments; // => Group<Comment>
  8. Handle Firestore data types with Typesaurus

    Typesaurus simplifies Firestore data handling by automatically converting Firestore timestamps into native JavaScript Date instances. It also preserves document references and undefined values, ensuring a more JavaScript-native experience.
  9. Understand Typesaurus architectural principles and design philosophy

    Typesaurus is designed to provide complete type-safety for reading from and writing to Firestore to prevent bugs and preserve data consistency. The architecture prioritizes the following values in order of importance:

    1. Safety guards: The type system is designed to prevent developers from making mistakes.
    2. Error clarity: Errors are intended to guide developers or be thoroughly documented.
    3. Simplicity: The resulting code is kept as simple as possible without compromising typings.

    Typesaurus adopts a "TypeScript-first" approach, meaning that if a trade-off must be made between API ease-of-use and the quality of the TypeScript types, the type system takes precedence to ensure the best possible experience for TypeScript developers.

  10. Ensure Firestore data consistency with Typesaurus type-safety

    Typesaurus provides type-safety for Firestore databases to ensure data consistency. It achieves this by treating document IDs as distinct types, which prevents the accidental mixing of different ID types (e.g., preventing a user ID from being used where an account ID is expected). Additionally, it performs type-level validation on writes to prevent documents from entering inconsistent states.
  11. Ensure Firestore data consistency with Typesaurus type-safety

    Typesaurus provides type-safety for Firestore databases to ensure 100% data consistency. It achieves this by treating document IDs as distinct types, which prevents the accidental mixing of different ID types (e.g., preventing a user ID from being used where an account ID is expected). Additionally, Typesaurus validates writes at the type-level to prevent documents from entering inconsistent states.
  12. Prevent data inconsistency with Typesaurus Safe Paths

    Typesaurus implements 'safe paths' to prevent partial updates that would leave a document in an impossible state. If you attempt to update a specific field within an optional nested object (e.g., $.field("address", "street")), Typesaurus may throw a type error (often appearing as never) if that update would result in the parent object missing other required fields defined in the interface. This ensures that if a nested object exists, it always conforms to its full type definition.