Basic Example
A basic generic store and a store that extends it.
Generic Store
ts
type ProductStore<T> = PiniaStore<'product', {
all: T[]
}, {
getTotal: () => number
getMaxPrice: () => number
}, {
add: (item: T) => void
}>
ts
interface ProductState<T> {
all: T[]
}
interface ProductGetters {
getTotal: () => number
getMaxPrice: () => number
}
interface ProductActions<T> {
add: (item: T) => void
}
type ProductStore<T> = PiniaStore<'product', ProductState<T>, ProductGetters, ProductActions<T>>
ts
function productStore<T extends Book>() {
return defineGenericStore<ProductStore<T>>({
state: {
all: [],
},
getters: {
getTotal() {
return this.all.reduce((total, item) => total + item.price, 0)
},
getMaxPrice() {
return this.all.reduce((max, item) => Math.max(max, item.price), 0)
},
},
actions: {
add(item: T) {
this.all.push(item)
},
},
})
}
ts
function productState<T>() {
return createState<ProductStore<T>>({
all: [],
})
}
function productGetters<T extends Book>() {
return createGetters<ProductStore<T>>({
getTotal() {
return this.all.reduce((total, item) => total + item.price, 0)
},
getMaxPrice() {
return this.all.reduce((max, item) => Math.max(max, item.price), 0)
},
})
}
function productActions<T>() {
return createActions<ProductStore<T>>({
add(item: T) {
this.all.push(item)
},
})
}
function productStore<T extends Book>() {
return defineGenericStore<ProductStore<T>>({
state: productState<T>(),
getters: productGetters<T>(),
actions: productActions<T>(),
})
}
Using the Generic Store
Type that will go in the place of T
.
ts
interface Book {
id: number
name: string
price: number
}
Store type
ts
type BookStore = PiniaStore<'book', {
active: Book | null
}, {
getAveragePrice: () => number
}, object, ProductStore<Book>>
ts
interface BookState {
active: Book | null
}
interface BookGetters {
getAveragePrice: () => number
}
type BookStore = PiniaStore<'book', BookState, BookGetters, object, ProductStore<Book>>
Creating the store
ts
export const useBookStore = useStore<BookStore, ProductStore<Book>>('book', {
state: {
active: null,
all: [
{ id: 1, name: 'The Lord of the Rings', price: 20 },
{ id: 2, name: 'The Hitchhiker\'s Guide to the Galaxy', price: 42 },
{ id: 3, name: 'The Little Prince', price: 10 },
],
},
getters: {
getAveragePrice() {
return this.getTotal / this.all.length
},
},
}, productStore<Book>(),)
ts
const bookState = createState<BookStore, ProductStore<Book>>({
active: null,
all: [
{ id: 1, name: 'The Lord of the Rings', price: 20 },
{ id: 2, name: 'The Hitchhiker\'s Guide to the Galaxy', price: 42 },
{ id: 3, name: 'The Little Prince', price: 10 },
],
})
const bookGetters = createGetters<BookStore, ProductStore<Book>>({
getAveragePrice() {
return this.getTotal / this.all.length
},
})
export const useBookStore = useStore<BookStore, ProductStore<Book>>('book', {
state: bookState,
getters: bookGetters,
}, productStore<Book>(),)