Svelte Custom Stores Declaração TypeScript

Jan 23 2023
Como declarar os tipos de lojas personalizadas? Svelte oferece alguns conceitos de loja fáceis de usar. Um deles são os “armazenamentos personalizados”, que facilitam a ofuscação dos dados armazenados reativos e seu acesso por meio de um conjunto de funções definidas de maneira personalizada.

Como declarar os tipos de lojas personalizadas?

Svelte oferece alguns conceitos de loja fáceis de usar. Um deles são os “ armazenamentos personalizados ”, que facilitam a ofuscação dos dados armazenados reativos e seu acesso por meio de um conjunto de funções definidas de maneira personalizada.

Por exemplo, um contador que conta maçãs e bananas, posso criar uma loja personalizada que não exponha diretamente meus dados. Dentro de uma função, posso “esconder” a loja e expor apenas as funções que quero usar em meus apps ao invés de expor publicamente sete update. Isso para evitar mau comportamento e mudanças inesperadas, o que pode ser muito útil à medida que a base de código cresce.

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();

Observe que eu simplesmente não implementei as funções relacionadas às “maçãs” para manter o snippet pequeno. Em um caso de uso real eu poderia até ter extraído a update()parte para uma função para evitar código duplo mas, também pulei essa parte porque não teria muito valor nesse contexto de post de blog.

Ao vincular um componente, funciona conforme o esperado.

No entanto, mesmo que npm run dev|build|checkesteja tudo bem, o Webstorm não consegue derivar os valores da loja quando usado em um scriptbloco TypeScript.

Não sei exatamente se é mais um problema do plugin Jetbrains Svelte ou se a loja é derivada como anytipo pelo bundler (que iria ignorar a strictopção). No entanto, prefiro corrigir o problema melhorando o tipo de declaração da loja.

Como minha loja personalizada expõe minhas funções caseiras, mas também o subscriberecurso , sua declaração também deve fornecer suporte para isso.

​Portanto, a maneira mais fácil, na minha opinião, é herdar o Readabletipo de Svelte.

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

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

Posso usar essa nova interface para definir o tipo de retorno da função de inicialização — initStore​— e é isso.

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();

Ao infinito e além
David

​​Para mais aventuras, siga-me no Twitter .