mirror of
https://github.com/StepanovPlaton/jelly_belly_wiki.git
synced 2026-04-03 20:30:41 +04:00
09-07
This commit is contained in:
19
src/entities/item/beans/index.ts
Normal file
19
src/entities/item/beans/index.ts
Normal file
@@ -0,0 +1,19 @@
|
||||
import {
|
||||
beanSchema,
|
||||
beansSchema,
|
||||
pageOfBeansSchema,
|
||||
thisItemIsBean,
|
||||
type BeanType,
|
||||
type PageOfBeansType,
|
||||
} from "./schema";
|
||||
export {
|
||||
beanSchema,
|
||||
beansSchema,
|
||||
pageOfBeansSchema,
|
||||
thisItemIsBean,
|
||||
type BeanType,
|
||||
type PageOfBeansType,
|
||||
};
|
||||
|
||||
import { BeansService } from "./service";
|
||||
export { BeansService };
|
||||
51
src/entities/item/beans/schema.ts
Normal file
51
src/entities/item/beans/schema.ts
Normal file
@@ -0,0 +1,51 @@
|
||||
import { z } from "zod";
|
||||
import { ItemType, TypesOfItems } from "../types";
|
||||
|
||||
export const beanSchema = z.object({
|
||||
beanId: z.number(),
|
||||
groupName: z.array(z.string()),
|
||||
ingredients: z.array(z.string()),
|
||||
flavorName: z.string(),
|
||||
description: z.string(),
|
||||
colorGroup: z.string(),
|
||||
backgroundColor: z.string(),
|
||||
imageUrl: z.string(),
|
||||
glutenFree: z.boolean(),
|
||||
sugarFree: z.boolean(),
|
||||
seasonal: z.boolean(),
|
||||
kosher: z.boolean(),
|
||||
|
||||
// Показывает, что этот item - bean
|
||||
type: z
|
||||
.any()
|
||||
.optional()
|
||||
.transform(() => TypesOfItems.bean),
|
||||
});
|
||||
export type BeanType = z.infer<typeof beanSchema>;
|
||||
|
||||
export const isBean = (a: any): a is BeanType => {
|
||||
return beanSchema.safeParse(a).success;
|
||||
};
|
||||
|
||||
export const beansSchema = z.array(z.any()).transform((a) => {
|
||||
const beans: BeanType[] = [];
|
||||
a.forEach((e) => {
|
||||
if (isBean(e)) beans.push(beanSchema.parse(e));
|
||||
else console.error("Bean parse error - ", e);
|
||||
});
|
||||
return beans;
|
||||
});
|
||||
|
||||
export const pageOfBeansSchema = z.object({
|
||||
totalCount: z.number(),
|
||||
pageSize: z.number(),
|
||||
currentPage: z.number(),
|
||||
totalPages: z.number(),
|
||||
items: beansSchema,
|
||||
});
|
||||
|
||||
export type PageOfBeansType = z.infer<typeof pageOfBeansSchema>;
|
||||
|
||||
export const thisItemIsBean = (i: ItemType): i is BeanType => {
|
||||
return (i as BeanType).type === TypesOfItems.bean;
|
||||
};
|
||||
29
src/entities/item/beans/service.ts
Normal file
29
src/entities/item/beans/service.ts
Normal file
@@ -0,0 +1,29 @@
|
||||
import { HTTPService } from "@/shared/utils/http";
|
||||
import { IItemService, staticImplements } from "../types";
|
||||
import { beanSchema, pageOfBeansSchema } from "./schema";
|
||||
|
||||
@staticImplements<IItemService>()
|
||||
export abstract class BeansService {
|
||||
public static urlPrefix = "beans";
|
||||
public static cacheOptions = {
|
||||
next: {
|
||||
revalidate: 60 * 5,
|
||||
},
|
||||
};
|
||||
|
||||
public static async Get(id: number) {
|
||||
return await HTTPService.get(
|
||||
`/${this.urlPrefix}/${id}`,
|
||||
beanSchema,
|
||||
this.cacheOptions
|
||||
);
|
||||
}
|
||||
|
||||
public static async GetPage(page: number, pageSize?: number) {
|
||||
return await HTTPService.get(
|
||||
`/${this.urlPrefix}?pageIndex=${page}&pageSize=${pageSize ?? 2 * 3 * 2}`,
|
||||
pageOfBeansSchema,
|
||||
this.cacheOptions
|
||||
);
|
||||
}
|
||||
}
|
||||
19
src/entities/item/combinations/index.ts
Normal file
19
src/entities/item/combinations/index.ts
Normal file
@@ -0,0 +1,19 @@
|
||||
import {
|
||||
combinationSchema,
|
||||
combinationsSchema,
|
||||
pageOfCombinationsSchema,
|
||||
thisItemIsCombination,
|
||||
type CombinationType,
|
||||
type PageOfCombinationsType,
|
||||
} from "./schema";
|
||||
export {
|
||||
combinationSchema,
|
||||
combinationsSchema,
|
||||
pageOfCombinationsSchema,
|
||||
thisItemIsCombination,
|
||||
type CombinationType,
|
||||
type PageOfCombinationsType,
|
||||
};
|
||||
|
||||
import { CombinationsService } from "./service";
|
||||
export { CombinationsService };
|
||||
42
src/entities/item/combinations/schema.ts
Normal file
42
src/entities/item/combinations/schema.ts
Normal file
@@ -0,0 +1,42 @@
|
||||
import { z } from "zod";
|
||||
import { ItemType, TypesOfItems } from "../types";
|
||||
|
||||
export const combinationSchema = z.object({
|
||||
combinationId: z.number(),
|
||||
name: z.string(),
|
||||
tag: z.array(z.string()),
|
||||
|
||||
// Показывает, что этот item - combination
|
||||
type: z
|
||||
.any()
|
||||
.optional()
|
||||
.transform(() => TypesOfItems.combination),
|
||||
});
|
||||
export type CombinationType = z.infer<typeof combinationSchema>;
|
||||
|
||||
export const isCombination = (a: any): a is CombinationType => {
|
||||
return combinationSchema.safeParse(a).success;
|
||||
};
|
||||
|
||||
export const combinationsSchema = z.array(z.any()).transform((a) => {
|
||||
const combinations: CombinationType[] = [];
|
||||
a.forEach((e) => {
|
||||
if (isCombination(e)) combinations.push(combinationSchema.parse(e));
|
||||
else console.error("Combination parse error - ", e);
|
||||
});
|
||||
return combinations;
|
||||
});
|
||||
|
||||
export const pageOfCombinationsSchema = z.object({
|
||||
totalCount: z.number(),
|
||||
pageSize: z.number(),
|
||||
currentPage: z.number(),
|
||||
totalPages: z.number(),
|
||||
items: combinationsSchema,
|
||||
});
|
||||
|
||||
export type PageOfCombinationsType = z.infer<typeof pageOfCombinationsSchema>;
|
||||
|
||||
export const thisItemIsCombination = (i: ItemType): i is CombinationType => {
|
||||
return (i as CombinationType).type === TypesOfItems.combination;
|
||||
};
|
||||
29
src/entities/item/combinations/service.ts
Normal file
29
src/entities/item/combinations/service.ts
Normal file
@@ -0,0 +1,29 @@
|
||||
import { HTTPService } from "@/shared/utils/http";
|
||||
import { IItemService, staticImplements } from "../types";
|
||||
import { combinationSchema, pageOfCombinationsSchema } from "./schema";
|
||||
|
||||
@staticImplements<IItemService>()
|
||||
export abstract class CombinationsService {
|
||||
public static urlPrefix = "combinations";
|
||||
public static cacheOptions = {
|
||||
next: {
|
||||
revalidate: 60 * 5,
|
||||
},
|
||||
};
|
||||
|
||||
public static async Get(id: number) {
|
||||
return await HTTPService.get(
|
||||
`/${this.urlPrefix}/${id}`,
|
||||
combinationSchema,
|
||||
this.cacheOptions
|
||||
);
|
||||
}
|
||||
|
||||
public static async GetPage(page: number, pageSize?: number) {
|
||||
return await HTTPService.get(
|
||||
`/${this.urlPrefix}?pageIndex=${page}&pageSize=${pageSize ?? 2 * 3 * 3}`,
|
||||
pageOfCombinationsSchema,
|
||||
this.cacheOptions
|
||||
);
|
||||
}
|
||||
}
|
||||
19
src/entities/item/facts/index.ts
Normal file
19
src/entities/item/facts/index.ts
Normal file
@@ -0,0 +1,19 @@
|
||||
import {
|
||||
factSchema,
|
||||
factsSchema,
|
||||
pageOfFactsSchema,
|
||||
thisItemIsFact,
|
||||
type FactType,
|
||||
type PageOfFactsType,
|
||||
} from "./schema";
|
||||
export {
|
||||
factSchema,
|
||||
factsSchema,
|
||||
pageOfFactsSchema,
|
||||
thisItemIsFact,
|
||||
type FactType,
|
||||
type PageOfFactsType,
|
||||
};
|
||||
|
||||
import { FactsService } from "./service";
|
||||
export { FactsService };
|
||||
42
src/entities/item/facts/schema.ts
Normal file
42
src/entities/item/facts/schema.ts
Normal file
@@ -0,0 +1,42 @@
|
||||
import { z } from "zod";
|
||||
import { ItemType, TypesOfItems } from "../types";
|
||||
|
||||
export const factSchema = z.object({
|
||||
factId: z.number(),
|
||||
title: z.string(),
|
||||
description: z.string(),
|
||||
|
||||
// Показывает, что этот item - fact
|
||||
type: z
|
||||
.any()
|
||||
.optional()
|
||||
.transform(() => TypesOfItems.fact),
|
||||
});
|
||||
export type FactType = z.infer<typeof factSchema>;
|
||||
|
||||
export const isFact = (a: any): a is FactType => {
|
||||
return factSchema.safeParse(a).success;
|
||||
};
|
||||
|
||||
export const factsSchema = z.array(z.any()).transform((a) => {
|
||||
const facts: FactType[] = [];
|
||||
a.forEach((e) => {
|
||||
if (isFact(e)) facts.push(factSchema.parse(e));
|
||||
else console.error("Fact parse error - ", e);
|
||||
});
|
||||
return facts;
|
||||
});
|
||||
|
||||
export const pageOfFactsSchema = z.object({
|
||||
totalCount: z.number(),
|
||||
pageSize: z.number(),
|
||||
currentPage: z.number(),
|
||||
totalPages: z.number(),
|
||||
items: factsSchema,
|
||||
});
|
||||
|
||||
export type PageOfFactsType = z.infer<typeof pageOfFactsSchema>;
|
||||
|
||||
export const thisItemIsFact = (i: ItemType): i is FactType => {
|
||||
return (i as FactType).type === TypesOfItems.fact;
|
||||
};
|
||||
29
src/entities/item/facts/service.ts
Normal file
29
src/entities/item/facts/service.ts
Normal file
@@ -0,0 +1,29 @@
|
||||
import { HTTPService } from "@/shared/utils/http";
|
||||
import { IItemService, staticImplements } from "../types";
|
||||
import { factSchema, pageOfFactsSchema } from "./schema";
|
||||
|
||||
@staticImplements<IItemService>()
|
||||
export abstract class FactsService {
|
||||
public static urlPrefix = "facts";
|
||||
public static cacheOptions = {
|
||||
next: {
|
||||
revalidate: 60 * 5,
|
||||
},
|
||||
};
|
||||
|
||||
public static async Get(id: number) {
|
||||
return await HTTPService.get(
|
||||
`/${this.urlPrefix}/${id}`,
|
||||
factSchema,
|
||||
this.cacheOptions
|
||||
);
|
||||
}
|
||||
|
||||
public static async GetPage(page: number, pageSize?: number) {
|
||||
return await HTTPService.get(
|
||||
`/${this.urlPrefix}?pageIndex=${page}&pageSize=${pageSize ?? 2 * 3 * 3}`,
|
||||
pageOfFactsSchema,
|
||||
this.cacheOptions
|
||||
);
|
||||
}
|
||||
}
|
||||
22
src/entities/item/index.ts
Normal file
22
src/entities/item/index.ts
Normal file
@@ -0,0 +1,22 @@
|
||||
import { thisItemIsBean, type BeanType } from "./beans";
|
||||
export { thisItemIsBean, type BeanType };
|
||||
|
||||
import { thisItemIsFact, type FactType } from "./facts";
|
||||
export { thisItemIsFact, type FactType };
|
||||
|
||||
import { thisItemIsRecipe, type RecipeType } from "./recipes";
|
||||
export { thisItemIsRecipe, type RecipeType };
|
||||
|
||||
import { thisItemIsCombination, type CombinationType } from "./combinations";
|
||||
export { thisItemIsCombination, type CombinationType };
|
||||
|
||||
import { ItemService } from "./item";
|
||||
export { ItemService };
|
||||
|
||||
import {
|
||||
TypesOfItems,
|
||||
type IItemService,
|
||||
type ItemType,
|
||||
type PageOfItemsType,
|
||||
} from "./types";
|
||||
export { TypesOfItems, type IItemService, type ItemType, type PageOfItemsType };
|
||||
49
src/entities/item/item.ts
Normal file
49
src/entities/item/item.ts
Normal file
@@ -0,0 +1,49 @@
|
||||
import { BeansService, thisItemIsBean } from "./beans";
|
||||
import { CombinationsService, thisItemIsCombination } from "./combinations";
|
||||
import { FactsService, thisItemIsFact } from "./facts";
|
||||
import { MileStonesService, thisItemIsMileStone } from "./mileStones";
|
||||
import { RecipesService, thisItemIsRecipe } from "./recipes";
|
||||
import { IItemService, ItemType, TypesOfItems } from "./types";
|
||||
|
||||
export abstract class ItemService {
|
||||
static get itemsConfiguration(): {
|
||||
[k in TypesOfItems]: {
|
||||
service: IItemService;
|
||||
};
|
||||
} {
|
||||
return {
|
||||
[TypesOfItems.bean]: {
|
||||
service: BeansService,
|
||||
},
|
||||
[TypesOfItems.fact]: {
|
||||
service: FactsService,
|
||||
},
|
||||
[TypesOfItems.recipe]: {
|
||||
service: RecipesService,
|
||||
},
|
||||
[TypesOfItems.combination]: {
|
||||
service: CombinationsService,
|
||||
},
|
||||
[TypesOfItems.mileStone]: {
|
||||
service: MileStonesService,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
public static GetTypeOfItem(i: ItemType): TypesOfItems {
|
||||
if (thisItemIsBean(i)) return TypesOfItems.bean;
|
||||
if (thisItemIsFact(i)) return TypesOfItems.fact;
|
||||
if (thisItemIsRecipe(i)) return TypesOfItems.recipe;
|
||||
if (thisItemIsCombination(i)) return TypesOfItems.combination;
|
||||
if (thisItemIsMileStone(i)) return TypesOfItems.mileStone;
|
||||
throw Error("unknown Item");
|
||||
}
|
||||
public static GetItemId(i: ItemType): number {
|
||||
if (thisItemIsBean(i)) return i.beanId;
|
||||
if (thisItemIsFact(i)) return i.factId;
|
||||
if (thisItemIsRecipe(i)) return i.recipeId;
|
||||
if (thisItemIsCombination(i)) return i.combinationId;
|
||||
if (thisItemIsMileStone(i)) return i.mileStoneId;
|
||||
throw Error("unknown Item");
|
||||
}
|
||||
}
|
||||
19
src/entities/item/mileStones/index.ts
Normal file
19
src/entities/item/mileStones/index.ts
Normal file
@@ -0,0 +1,19 @@
|
||||
import {
|
||||
mileStoneSchema,
|
||||
mileStonesSchema,
|
||||
pageOfMileStonesSchema,
|
||||
thisItemIsMileStone,
|
||||
type MileStoneType,
|
||||
type PageOfMileStonesType,
|
||||
} from "./schema";
|
||||
export {
|
||||
mileStoneSchema,
|
||||
mileStonesSchema,
|
||||
pageOfMileStonesSchema,
|
||||
thisItemIsMileStone,
|
||||
type MileStoneType,
|
||||
type PageOfMileStonesType,
|
||||
};
|
||||
|
||||
import { MileStonesService } from "./service";
|
||||
export { MileStonesService };
|
||||
42
src/entities/item/mileStones/schema.ts
Normal file
42
src/entities/item/mileStones/schema.ts
Normal file
@@ -0,0 +1,42 @@
|
||||
import { z } from "zod";
|
||||
import { ItemType, TypesOfItems } from "../types";
|
||||
|
||||
export const mileStoneSchema = z.object({
|
||||
mileStoneId: z.number(),
|
||||
year: z.number(),
|
||||
description: z.string(),
|
||||
|
||||
// Показывает, что этот item - mileStone
|
||||
type: z
|
||||
.any()
|
||||
.optional()
|
||||
.transform(() => TypesOfItems.mileStone),
|
||||
});
|
||||
export type MileStoneType = z.infer<typeof mileStoneSchema>;
|
||||
|
||||
export const isMileStone = (a: any): a is MileStoneType => {
|
||||
return mileStoneSchema.safeParse(a).success;
|
||||
};
|
||||
|
||||
export const mileStonesSchema = z.array(z.any()).transform((a) => {
|
||||
const mileStones: MileStoneType[] = [];
|
||||
a.forEach((e) => {
|
||||
if (isMileStone(e)) mileStones.push(mileStoneSchema.parse(e));
|
||||
else console.error("MileStone parse error - ", e);
|
||||
});
|
||||
return mileStones;
|
||||
});
|
||||
|
||||
export const pageOfMileStonesSchema = z.object({
|
||||
totalCount: z.number(),
|
||||
pageSize: z.number(),
|
||||
currentPage: z.number(),
|
||||
totalPages: z.number(),
|
||||
items: mileStonesSchema,
|
||||
});
|
||||
|
||||
export type PageOfMileStonesType = z.infer<typeof pageOfMileStonesSchema>;
|
||||
|
||||
export const thisItemIsMileStone = (i: ItemType): i is MileStoneType => {
|
||||
return (i as MileStoneType).type === TypesOfItems.mileStone;
|
||||
};
|
||||
29
src/entities/item/mileStones/service.ts
Normal file
29
src/entities/item/mileStones/service.ts
Normal file
@@ -0,0 +1,29 @@
|
||||
import { HTTPService } from "@/shared/utils/http";
|
||||
import { IItemService, staticImplements } from "../types";
|
||||
import { mileStoneSchema, pageOfMileStonesSchema } from "./schema";
|
||||
|
||||
@staticImplements<IItemService>()
|
||||
export abstract class MileStonesService {
|
||||
public static urlPrefix = "mileStones";
|
||||
public static cacheOptions = {
|
||||
next: {
|
||||
revalidate: 60 * 5,
|
||||
},
|
||||
};
|
||||
|
||||
public static async Get(id: number) {
|
||||
return await HTTPService.get(
|
||||
`/${this.urlPrefix}/${id}`,
|
||||
mileStoneSchema,
|
||||
this.cacheOptions
|
||||
);
|
||||
}
|
||||
|
||||
public static async GetPage(page: number, pageSize?: number) {
|
||||
return await HTTPService.get(
|
||||
`/${this.urlPrefix}?pageIndex=${page}&pageSize=${pageSize ?? 2 * 3 * 3}`,
|
||||
pageOfMileStonesSchema,
|
||||
this.cacheOptions
|
||||
);
|
||||
}
|
||||
}
|
||||
19
src/entities/item/recipes/index.ts
Normal file
19
src/entities/item/recipes/index.ts
Normal file
@@ -0,0 +1,19 @@
|
||||
import {
|
||||
recipeSchema,
|
||||
recipesSchema,
|
||||
pageOfRecipesSchema,
|
||||
thisItemIsRecipe,
|
||||
type RecipeType,
|
||||
type PageOfRecipesType,
|
||||
} from "./schema";
|
||||
export {
|
||||
recipeSchema,
|
||||
recipesSchema,
|
||||
pageOfRecipesSchema,
|
||||
thisItemIsRecipe,
|
||||
type RecipeType,
|
||||
type PageOfRecipesType,
|
||||
};
|
||||
|
||||
import { RecipesService } from "./service";
|
||||
export { RecipesService };
|
||||
53
src/entities/item/recipes/schema.ts
Normal file
53
src/entities/item/recipes/schema.ts
Normal file
@@ -0,0 +1,53 @@
|
||||
import { z } from "zod";
|
||||
import { ItemType, TypesOfItems } from "../types";
|
||||
|
||||
export const recipeSchema = z.object({
|
||||
recipeId: z.number(),
|
||||
name: z.string(),
|
||||
description: z.string(),
|
||||
prepTime: z.string(),
|
||||
cookTime: z.string(),
|
||||
totalTime: z.string(),
|
||||
makingAmount: z.string(),
|
||||
imageUrl: z.string(),
|
||||
ingredients: z.array(z.string()),
|
||||
additions1: z.array(z.string()),
|
||||
additions2: z.array(z.unknown()),
|
||||
additions3: z.array(z.unknown()),
|
||||
directions: z.array(z.string()),
|
||||
tips: z.array(z.string()),
|
||||
|
||||
// Показывает, что этот item - recipe
|
||||
type: z
|
||||
.any()
|
||||
.optional()
|
||||
.transform(() => TypesOfItems.recipe),
|
||||
});
|
||||
export type RecipeType = z.infer<typeof recipeSchema>;
|
||||
|
||||
export const isRecipe = (a: any): a is RecipeType => {
|
||||
return recipeSchema.safeParse(a).success;
|
||||
};
|
||||
|
||||
export const recipesSchema = z.array(z.any()).transform((a) => {
|
||||
const recipes: RecipeType[] = [];
|
||||
a.forEach((e) => {
|
||||
if (isRecipe(e)) recipes.push(recipeSchema.parse(e));
|
||||
else console.error("Recipe parse error - ", e);
|
||||
});
|
||||
return recipes;
|
||||
});
|
||||
|
||||
export const pageOfRecipesSchema = z.object({
|
||||
totalCount: z.number(),
|
||||
pageSize: z.number(),
|
||||
currentPage: z.number(),
|
||||
totalPages: z.number(),
|
||||
items: recipesSchema,
|
||||
});
|
||||
|
||||
export type PageOfRecipesType = z.infer<typeof pageOfRecipesSchema>;
|
||||
|
||||
export const thisItemIsRecipe = (i: ItemType): i is RecipeType => {
|
||||
return (i as RecipeType).type === TypesOfItems.recipe;
|
||||
};
|
||||
29
src/entities/item/recipes/service.ts
Normal file
29
src/entities/item/recipes/service.ts
Normal file
@@ -0,0 +1,29 @@
|
||||
import { HTTPService } from "@/shared/utils/http";
|
||||
import { IItemService, staticImplements } from "../types";
|
||||
import { recipeSchema, pageOfRecipesSchema } from "./schema";
|
||||
|
||||
@staticImplements<IItemService>()
|
||||
export abstract class RecipesService {
|
||||
public static urlPrefix = "recipes";
|
||||
public static cacheOptions = {
|
||||
next: {
|
||||
revalidate: 60 * 5,
|
||||
},
|
||||
};
|
||||
|
||||
public static async Get(id: number) {
|
||||
return await HTTPService.get(
|
||||
`/${this.urlPrefix}/${id}`,
|
||||
recipeSchema,
|
||||
this.cacheOptions
|
||||
);
|
||||
}
|
||||
|
||||
public static async GetPage(page: number, pageSize?: number) {
|
||||
return await HTTPService.get(
|
||||
`/${this.urlPrefix}?pageIndex=${page}&pageSize=${pageSize ?? 2 * 3 * 2}`,
|
||||
pageOfRecipesSchema,
|
||||
this.cacheOptions
|
||||
);
|
||||
}
|
||||
}
|
||||
37
src/entities/item/types.ts
Normal file
37
src/entities/item/types.ts
Normal file
@@ -0,0 +1,37 @@
|
||||
import { BeanType, PageOfBeansType } from "./beans";
|
||||
import { CombinationType, PageOfCombinationsType } from "./combinations";
|
||||
import { FactType, PageOfFactsType } from "./facts";
|
||||
import { MileStoneType, PageOfMileStonesType } from "./mileStones";
|
||||
import { PageOfRecipesType, RecipeType } from "./recipes";
|
||||
|
||||
export type ItemType =
|
||||
| BeanType
|
||||
| FactType
|
||||
| RecipeType
|
||||
| CombinationType
|
||||
| MileStoneType;
|
||||
export type PageOfItemsType =
|
||||
| PageOfBeansType
|
||||
| PageOfFactsType
|
||||
| PageOfRecipesType
|
||||
| PageOfCombinationsType
|
||||
| PageOfMileStonesType;
|
||||
|
||||
export enum TypesOfItems {
|
||||
bean,
|
||||
fact,
|
||||
recipe,
|
||||
combination,
|
||||
mileStone,
|
||||
}
|
||||
|
||||
export interface IItemService {
|
||||
urlPrefix: string;
|
||||
Get(id: number): Promise<ItemType | null>;
|
||||
GetPage(page: number, pageSize?: number): Promise<PageOfItemsType | null>;
|
||||
}
|
||||
|
||||
export const staticImplements =
|
||||
<T>() =>
|
||||
<U extends T>(constructor: U) =>
|
||||
constructor;
|
||||
Reference in New Issue
Block a user