Appearance
Implementing the Options API Style 
Building upon our implementation of the Composition API style for defineStore and global Pinia instance access (activePinia), we will now add support for the Options API pattern. Pinia provides both styles to cater to different preferences and existing codebases, allowing developers to choose the one they are most comfortable with or which best suits their project.
The core strategy for implementing the Options API style without duplicating the store creation logic (createSetupStore) is to internally convert the Options API definition (state, getters, actions object) into an equivalent Setup API function. This dynamically generated Setup function can then be processed by the createSetupStore function we already built.
Conceptually, the flow for a store defined using the Options API will be: defineStore() → createOptionsStore() → generate equivalent setup function → createSetupStore() → return store instance
Options API Usage Example 
Before diving into the implementation, let's look at the familiar Options API pattern for defining a store, as shown in the official documentation:
typescript
import { defineStore } from 'pinia'
export const useCounterStore = defineStore('counter', {
  state: () => {
    return { count: 0 }
  },
  getters: {
    doubleCount(): number {
      return this.count * 2;
    },
  },
  actions: {
    increment() {
      this.count++
    },
  },
})This structure is similar to Vue's Options API for components, with distinct sections for state (defined by a factory function), getters (computed properties), and actions (methods). A key characteristic here is the expectation that this within getters and actions will refer to the store instance itself, allowing access to state (this.count) and potentially other getters or actions (this.someOtherGetter). Our implementation must ensure this this context is correctly bound.
Implementing the Options API Logic 
To support both the Setup and Options API styles, our defineStore function needs to accept either a setup function or an options object as its second argument. In TypeScript, this is achieved using function overloads.
defineStore Overloads 
Now, update the defineStore function signature overloaded signatures to accept either a setup function or an options object. The implementation signature needs to accept a parameter that could be either.
typescript
// store.ts
// options api  type
export function defineStore<
  Id extends string,
  S extends StateTree = {},
  G extends _GettersTree<S> = {},
  A = {}
>(
  id: Id,
  options: Omit<DefineStoreOptions<Id, S, G, A>, "id">
): StoreDefinition<Id, S, G, A>;
// setup function
export function defineStore<Id extends string, SS extends Record<any, unknown>>(
  id: any,
  setup: () => SS
): StoreDefinition<
  string,
  _ExtractStateFromSetupStore<SS>,
  _ExtractGettersFromSetupStore<SS>,
  _ExtractActionsFromSetupStore<SS>
>;
export function defineStore(id: any, setup?: any): StoreDefinition {}createOptionsStore 
Added createOptionsStore function which generates the setup function, handling state, actions, and particularly getters with this binding via .call(store, store). Updated the createSetupStore signature to accept the isOptions flag and ensured necessary imports.)
fix the useStore
typescript
// store.ts
    if (!pinia._s.has(id)) {
      if (isSetupStore) {
        createSetupStore(id, setup, pinia);
      } else {
        createOptionsStore(id, setup, pinia);
      }
    }typescript
// store.ts
function createOptionsStore<
  Id extends string,
  S extends StateTree,
  G extends _GettersTree<S>,
  A extends _ActionsTree
>(
  id: Id,
  options: DefineStoreOptions<Id, S, G, A>,
  pinia: Pinia
): Store<Id, S, G, A> {
  const { state, actions, getters } = options;
  let store: Store<Id, S, G, A>;
  function setup() {
    const localState = state ? state() : {};
    return Object.assign(
      localState,
      actions,
      Object.keys(getters || {}).reduce((computedGetters, name) => {
        if (name in localState) {
          console.warn(
            `[🍍]: A getter cannot have the same name as another state property. Rename one of them. Found with "${name}" in store "${id}".`
          );
        }
        computedGetters[name] = markRaw(
          computed(() => {
            setActivePinia(pinia);
            const store = pinia._s.get(id)!;
            // @ts-expect-error
            return getters![name].call(store, store);
          })
        );
        return computedGetters;
      }, {} as Record<string, ComputedRef>)
    );
  }
  store = createSetupStore(id, setup, pinia, true);
  return store;
}work 
You should see a screen similar to the previous screenshot, but driven by the Options API store:
typescript
export const useCounterOptionsSmallStore = defineStore("options-counter", {
  state: () => {
    return {
      count: 0,
    };
  },
  getters: {
    doubleCount(): number {
      return this.count * 2;
    },
  },
  actions: {
    increment() {
      this.count++;
    },
  },
});Reference: You can check the code I write in the pr link https://github.com/KOBATATU/small-pinia/pull/5
