Svelte Custom Stores Декларация TypeScript

Jan 23 2023
Как объявить типы пользовательских магазинов? Svelte предлагает несколько приятных и простых в использовании концепций магазина. Одним из них являются «настраиваемые хранилища», которые упрощают запутывание реактивных сохраненных данных и доступ к ним через набор настраиваемых функций.

Как объявить типы пользовательских магазинов?

Svelte предлагает несколько приятных и простых в использовании концепций магазина. Одним из них являются « пользовательские хранилища », которые упрощают запутывание реактивных сохраненных данных и доступ к ним через набор настраиваемых функций.

Например, счетчик, который считает яблоки и бананы, я могу создать кастомное хранилище, которое не раскрывает напрямую мои данные. Внутри функции я могу «скрыть» хранилище и выставить только те функции, которые я хочу использовать в своих приложениях, вместо того, чтобы выставлять их на всеобщее обозрение .set updateЭто позволяет избежать неправильного поведения и неожиданных изменений, что может быть очень полезно по мере роста базы кода.

import { writable } from 'svelte/store';

export interface Counter {
   apples: number;
   bananas: number;
}

const initStore = () => {
   const initialCounter: Counter = {
      apples: 0,
      bananas: 0
   };

   const { subscribe, set, update } =
      writable(initialCounter);

   return {
      subscribe,
      incBanana: () =>
         update(({ bananas, ...rest }) => ({
            ...rest,
            bananas: bananas + 1
         })),
      decBanana: () =>
         update(({ bananas, ...rest }) => ({
            ...rest,
            bananas: bananas - 1
         })),
      reset: () => set(initialCounter)
   };
};

export const counter = initStore();

Обратите внимание , что я просто не реализовал функции, связанные с «яблоками», чтобы фрагмент был небольшим. В реальном случае я мог бы даже извлечь update()часть в функцию, чтобы избежать двойного кода, но я также пропустил эту часть, потому что она не имела бы большого значения в контексте этого поста в блоге.

При привязке к компоненту он работает так, как ожидалось.

Однако, даже если npm run dev|build|checkвсе в порядке, Webstorm не может получить значения хранилища при использовании в scriptблоке TypeScript.

Я точно не знаю, является ли это еще одной проблемой плагина Jetbrains Svelte или тип хранилища определяется anyсборщиком (который игнорирует эту strictопцию). Тем не менее, я предпочел бы решить проблему, улучшив тип объявления хранилища.

Поскольку мой пользовательский магазин предоставляет мои самодельные функции, а также корневую subscribeфункцию , его объявление также должно обеспечивать ее поддержку.

Поэтому, на мой взгляд, проще всего унаследовать существующий Readableтип Svelte.

import {type Readable} from 'svelte/store';

export interface AuthStore extends Readable<Counter> {
   incBanana: () => void;
   decBanana: () => void;
   reset: () => void;
}

Я могу использовать этот новый интерфейс для установки возвращаемого типа функции инициализации — initStore​— и это уже все.

import { type Readable, writable } from 'svelte/store';

export interface Counter {
   apples: number;
   bananas: number;
}

export interface AuthStore extends Readable<Counter> {
   incBanana: () => void;
   decBanana: () => void;
   reset: () => void;
}

const initStore = (): AuthStore => {
   const initialCounter: Counter = {
      apples: 0,
      bananas: 0
   };

   const { subscribe, set, update } =
      writable(initialCounter);

   return {
      subscribe,
      incBanana: () =>
         update(({ bananas, ...rest }) => ({
            ...rest,
            bananas: bananas + 1
         })),
      decBanana: () =>
         update(({ bananas, ...rest }) => ({
            ...rest,
            bananas: bananas - 1
         })),
      reset: () => set(initialCounter)
   };
};

export const counter = initStore();

В бесконечность и за пределы
Давида

Чтобы узнать больше о приключениях, следите за мной в Твиттере .