TypeScript
react-mnemonic is written in strict TypeScript and ships its own declarations.
All public types are re-exported from the package root. Common helper functions
such as createSchemaRegistry(...) are also exported from the root package.
Type imports
import type {
Codec,
StorageLike,
MnemonicKeyDescriptor,
TypedJsonSchema,
InferJsonSchemaValue,
MnemonicProviderOptions,
MnemonicProviderProps,
UseMnemonicKeyOptions,
KeySchema,
MigrationRule,
MigrationPath,
SchemaRegistry,
StructuralTreeHelpers,
SchemaMode,
JsonSchema,
JsonSchemaType,
JsonSchemaValidationError,
CompiledValidator,
} from "react-mnemonic";
Generic inference
useMnemonicKey infers T from the defaultValue option:
// T is inferred as number
const { value, set } = useMnemonicKey("count", { defaultValue: 0 });
// T is inferred as { name: string; email: string }
const { value, set } = useMnemonicKey("profile", {
defaultValue: { name: "", email: "" },
});
You can also supply the generic explicitly:
const { value, set } = useMnemonicKey<"light" | "dark">("theme", {
defaultValue: "light",
});
Descriptor inference
defineMnemonicKey(...) preserves the inferred value type and packages the key
contract into a reusable object:
import { defineMnemonicKey, useMnemonicKey } from "react-mnemonic";
const themeKey = defineMnemonicKey("theme", {
defaultValue: "light" as "light" | "dark",
});
const { value, set } = useMnemonicKey(themeKey);
// `value` is inferred as "light" | "dark"
This is useful when the same durable key is shared across multiple components or generated code paths.
Schema/type cohesion
When you want a schema-managed key to derive its TypeScript type from the runtime schema object, use the typed schema helpers:
import { defineKeySchema, defineMnemonicKey, mnemonicSchema } from "react-mnemonic";
const themeSchema = defineKeySchema("theme", 1, mnemonicSchema.enum(["light", "dark"] as const));
const themeKey = defineMnemonicKey(themeSchema, {
defaultValue: "light",
reconcile: (value) => value,
});
In that flow:
defaultValueis inferred from the schemareconcile(value)receives the schema-derived value typeuseMnemonicKey(themeKey)returns the same inferred type
You can also work directly with the helper types:
const profileSchema: TypedJsonSchema<{
name: string;
email?: string;
}> = mnemonicSchema.object({
name: mnemonicSchema.string(),
email: mnemonicSchema.optional(mnemonicSchema.string()),
});
type Profile = InferJsonSchemaValue<typeof profileSchema>;
Key types
Codec<T>
Bidirectional serialization between T and string:
interface Codec<T> {
encode: (value: T) => string;
decode: (encoded: string) => T;
}
KeySchema
A versioned JSON Schema definition for a storage key:
interface KeySchema {
key: string;
version: number;
schema: JsonSchema;
}
MigrationRule
Defines how to transform data between schema versions:
interface MigrationRule {
key: string;
fromVersion: number;
toVersion: number;
migrate: (value: unknown) => unknown;
}
SchemaRegistry
The interface for registering schemas and resolving migrations:
interface SchemaRegistry {
getSchema(key: string, version: number): KeySchema | undefined;
getLatestSchema(key: string): KeySchema | undefined;
getMigrationPath(key: string, from: number, to: number): MigrationRule[] | null;
getWriteMigration?(key: string, version: number): MigrationRule | undefined;
registerSchema?(schema: KeySchema): void;
}
For immutable registries, prefer createSchemaRegistry({ schemas, migrations })
instead of manually implementing this interface.
StructuralTreeHelpers<T>
Adapter type for structural migration helpers when your tree does not use the
default id / children fields:
interface StructuralTreeHelpers<T> {
getId: (node: T) => string;
getChildren: (node: T) => readonly T[] | undefined;
withChildren: (node: T, children: T[]) => T;
withId: (node: T, id: string) => T;
}
SchemaMode
type SchemaMode = "default" | "strict" | "autoschema";
StorageLike
The minimal interface for pluggable storage backends. See Custom Storage for details. The contract is intentionally synchronous; async persistence belongs behind a sync facade.