Added FeatureOptionsFunc to simplify features

This commit is contained in:
thepaperpilot 2022-04-10 19:04:56 -05:00
parent 838ac46cf9
commit 64f1b460b0
21 changed files with 76 additions and 67 deletions

View file

@ -5,7 +5,7 @@ import {
GenericClickable GenericClickable
} from "features/clickables/clickable"; } from "features/clickables/clickable";
import { GenericConversion } from "features/conversion"; import { GenericConversion } from "features/conversion";
import { CoercableComponent, jsx, Replace, setDefault } from "features/feature"; import { CoercableComponent, OptionsFunc, jsx, Replace, setDefault } from "features/feature";
import { displayResource } from "features/resources/resource"; import { displayResource } from "features/resources/resource";
import { import {
createTreeNode, createTreeNode,
@ -57,7 +57,7 @@ export type GenericResetButton = Replace<
>; >;
export function createResetButton<T extends ClickableOptions & ResetButtonOptions>( export function createResetButton<T extends ClickableOptions & ResetButtonOptions>(
optionsFunc: () => T optionsFunc: OptionsFunc<T>
): ResetButton<T> { ): ResetButton<T> {
return createClickable(() => { return createClickable(() => {
const resetButton = optionsFunc(); const resetButton = optionsFunc();
@ -139,7 +139,7 @@ export type GenericLayerTreeNode = Replace<
>; >;
export function createLayerTreeNode<T extends LayerTreeNodeOptions>( export function createLayerTreeNode<T extends LayerTreeNodeOptions>(
optionsFunc: () => T optionsFunc: OptionsFunc<T>
): LayerTreeNode<T> { ): LayerTreeNode<T> {
return createTreeNode(() => { return createTreeNode(() => {
const options = optionsFunc(); const options = optionsFunc();

View file

@ -2,6 +2,7 @@ import AchievementComponent from "features/achievements/Achievement.vue";
import { import {
CoercableComponent, CoercableComponent,
Component, Component,
OptionsFunc,
GatherProps, GatherProps,
getUniqueID, getUniqueID,
Replace, Replace,
@ -67,12 +68,10 @@ export type GenericAchievement = Replace<
>; >;
export function createAchievement<T extends AchievementOptions>( export function createAchievement<T extends AchievementOptions>(
optionsFunc: () => T & ThisType<Achievement<T>> optionsFunc: OptionsFunc<T, Achievement<T>, BaseAchievement>
): Achievement<T> { ): Achievement<T> {
return createLazyProxy(persistent => { return createLazyProxy(persistent => {
// Create temp literally just to avoid explicitly assigning types const achievement = Object.assign(persistent, optionsFunc());
const temp = Object.assign(persistent, optionsFunc());
const achievement: Partial<BaseAchievement> & typeof temp = temp;
achievement.id = getUniqueID("achievement-"); achievement.id = getUniqueID("achievement-");
achievement.type = AchievementType; achievement.type = AchievementType;
achievement[Component] = AchievementComponent; achievement[Component] = AchievementComponent;

View file

@ -2,6 +2,7 @@ import BarComponent from "features/bars/Bar.vue";
import { import {
CoercableComponent, CoercableComponent,
Component, Component,
OptionsFunc,
GatherProps, GatherProps,
getUniqueID, getUniqueID,
Replace, Replace,
@ -79,9 +80,11 @@ export type GenericBar = Replace<
} }
>; >;
export function createBar<T extends BarOptions>(optionsFunc: () => T & ThisType<Bar<T>>): Bar<T> { export function createBar<T extends BarOptions>(
optionsFunc: OptionsFunc<T, Bar<T>, BaseBar>
): Bar<T> {
return createLazyProxy(() => { return createLazyProxy(() => {
const bar: T & Partial<BaseBar> = optionsFunc(); const bar = optionsFunc();
bar.id = getUniqueID("bar-"); bar.id = getUniqueID("bar-");
bar.type = BarType; bar.type = BarType;
bar[Component] = BarComponent; bar[Component] = BarComponent;

View file

@ -1,6 +1,7 @@
import BoardComponent from "features/boards/Board.vue"; import BoardComponent from "features/boards/Board.vue";
import { import {
Component, Component,
OptionsFunc,
findFeatures, findFeatures,
GatherProps, GatherProps,
getUniqueID, getUniqueID,
@ -197,13 +198,11 @@ export type GenericBoard = Replace<
>; >;
export function createBoard<T extends BoardOptions>( export function createBoard<T extends BoardOptions>(
optionsFunc: () => T & ThisType<Board<T>> optionsFunc: OptionsFunc<T, Board<T>, BaseBoard>
): Board<T> { ): Board<T> {
return createLazyProxy( return createLazyProxy(
persistent => { persistent => {
// Create temp literally just to avoid explicitly assigning types const board = Object.assign(persistent, optionsFunc());
const temp = Object.assign(persistent, optionsFunc());
const board: Partial<BaseBoard> & typeof temp = temp;
board.id = getUniqueID("board-"); board.id = getUniqueID("board-");
board.type = BoardType; board.type = BoardType;
board[Component] = BoardComponent; board[Component] = BoardComponent;

View file

@ -15,6 +15,7 @@ import { computed, Ref, unref } from "vue";
import { import {
CoercableComponent, CoercableComponent,
Component, Component,
OptionsFunc,
GatherProps, GatherProps,
getUniqueID, getUniqueID,
jsx, jsx,
@ -87,12 +88,10 @@ export type GenericBuyable = Replace<
>; >;
export function createBuyable<T extends BuyableOptions>( export function createBuyable<T extends BuyableOptions>(
optionsFunc: () => T & ThisType<Buyable<T>> optionsFunc: OptionsFunc<T, Buyable<T>, BaseBuyable>
): Buyable<T> { ): Buyable<T> {
return createLazyProxy(persistent => { return createLazyProxy(persistent => {
// Create temp literally just to avoid explicitly assigning types const buyable = Object.assign(persistent, optionsFunc());
const temp = Object.assign(persistent, optionsFunc());
const buyable: Partial<BaseBuyable> & typeof temp = temp;
if (buyable.canPurchase == null && (buyable.resource == null || buyable.cost == null)) { if (buyable.canPurchase == null && (buyable.resource == null || buyable.cost == null)) {
console.warn( console.warn(

View file

@ -4,6 +4,7 @@ import ChallengeComponent from "features/challenges/Challenge.vue";
import { import {
CoercableComponent, CoercableComponent,
Component, Component,
OptionsFunc,
GatherProps, GatherProps,
getUniqueID, getUniqueID,
jsx, jsx,
@ -96,12 +97,12 @@ export type GenericChallenge = Replace<
>; >;
export function createChallenge<T extends ChallengeOptions>( export function createChallenge<T extends ChallengeOptions>(
optionsFunc: () => T & ThisType<Challenge<T>> optionsFunc: OptionsFunc<T, Challenge<T>, BaseChallenge>
): Challenge<T> { ): Challenge<T> {
const completions = persistent(0); const completions = persistent(0);
const active = persistent(false); const active = persistent(false);
return createLazyProxy(() => { return createLazyProxy(() => {
const challenge: T & Partial<BaseChallenge> = optionsFunc(); const challenge = optionsFunc();
if ( if (
challenge.canComplete == null && challenge.canComplete == null &&

View file

@ -2,6 +2,7 @@ import ClickableComponent from "features/clickables/Clickable.vue";
import { import {
CoercableComponent, CoercableComponent,
Component, Component,
OptionsFunc,
GatherProps, GatherProps,
getUniqueID, getUniqueID,
Replace, Replace,
@ -69,10 +70,10 @@ export type GenericClickable = Replace<
>; >;
export function createClickable<T extends ClickableOptions>( export function createClickable<T extends ClickableOptions>(
optionsFunc: () => T & ThisType<Clickable<T>> optionsFunc: OptionsFunc<T, Clickable<T>, BaseClickable>
): Clickable<T> { ): Clickable<T> {
return createLazyProxy(() => { return createLazyProxy(() => {
const clickable: T & Partial<BaseClickable> = optionsFunc(); const clickable = optionsFunc();
clickable.id = getUniqueID("clickable-"); clickable.id = getUniqueID("clickable-");
clickable.type = ClickableType; clickable.type = ClickableType;
clickable[Component] = ClickableComponent; clickable[Component] = ClickableComponent;

View file

@ -1,17 +1,15 @@
import { GenericLayer } from "game/layers"; import { GenericLayer } from "game/layers";
import Decimal, { DecimalSource } from "util/bignum"; import Decimal, { DecimalSource } from "util/bignum";
import { isFunction } from "util/common";
import { import {
Computable, Computable,
convertComputable, convertComputable,
DoNotCache,
GetComputableTypeWithDefault, GetComputableTypeWithDefault,
processComputable, processComputable,
ProcessedComputable ProcessedComputable
} from "util/computed"; } from "util/computed";
import { createLazyProxy } from "util/proxies"; import { createLazyProxy } from "util/proxies";
import { computed, isRef, Ref, unref } from "vue"; import { computed, isRef, Ref, unref } from "vue";
import { Replace, setDefault } from "./feature"; import { OptionsFunc, Replace, setDefault } from "./feature";
import { Resource } from "./resources/resource"; import { Resource } from "./resources/resource";
export interface ConversionOptions { export interface ConversionOptions {
@ -62,10 +60,10 @@ export interface GainModifier {
} }
export function createConversion<T extends ConversionOptions>( export function createConversion<T extends ConversionOptions>(
optionsFunc: () => T & ThisType<Conversion<T>> optionsFunc: OptionsFunc<T, Conversion<T>, BaseConversion>
): Conversion<T> { ): Conversion<T> {
return createLazyProxy(() => { return createLazyProxy(() => {
const conversion: T = optionsFunc(); const conversion = optionsFunc();
if (conversion.currentGain == null) { if (conversion.currentGain == null) {
conversion.currentGain = computed(() => { conversion.currentGain = computed(() => {
@ -199,13 +197,13 @@ export function createPolynomialScaling(
} }
export function createCumulativeConversion<S extends ConversionOptions>( export function createCumulativeConversion<S extends ConversionOptions>(
optionsFunc: () => S & ThisType<Conversion<S>> optionsFunc: OptionsFunc<S, Conversion<S>>
): Conversion<S> { ): Conversion<S> {
return createConversion(optionsFunc); return createConversion(optionsFunc);
} }
export function createIndependentConversion<S extends ConversionOptions>( export function createIndependentConversion<S extends ConversionOptions>(
optionsFunc: () => S & ThisType<Conversion<S>> optionsFunc: OptionsFunc<S, Conversion<S>>
): Conversion<S> { ): Conversion<S> {
return createConversion(() => { return createConversion(() => {
const conversion: S = optionsFunc(); const conversion: S = optionsFunc();

View file

@ -24,6 +24,8 @@ export type FeatureComponent<T> = Omit<
export type Replace<T, S> = S & Omit<T, keyof S>; export type Replace<T, S> = S & Omit<T, keyof S>;
export type OptionsFunc<T, S = T, R = Record<string, unknown>> = () => T & ThisType<S> & Partial<R>;
let id = 0; let id = 0;
// Get a unique ID to allow a feature to be found for creating branches // Get a unique ID to allow a feature to be found for creating branches
// and any other uses requiring unique identifiers for each feature // and any other uses requiring unique identifiers for each feature

View file

@ -2,6 +2,7 @@ import GridComponent from "features/grids/Grid.vue";
import { import {
CoercableComponent, CoercableComponent,
Component, Component,
OptionsFunc,
GatherProps, GatherProps,
getUniqueID, getUniqueID,
Replace, Replace,
@ -241,12 +242,10 @@ export type GenericGrid = Replace<
>; >;
export function createGrid<T extends GridOptions>( export function createGrid<T extends GridOptions>(
optionsFunc: () => T & ThisType<Grid<T>> optionsFunc: OptionsFunc<T, Grid<T>, BaseGrid>
): Grid<T> { ): Grid<T> {
return createLazyProxy(persistent => { return createLazyProxy(persistent => {
// Create temp literally just to avoid explicitly assigning types const grid = Object.assign(persistent, optionsFunc());
const temp = Object.assign(persistent, optionsFunc());
const grid: Partial<BaseGrid> & typeof temp = temp;
grid.id = getUniqueID("grid-"); grid.id = getUniqueID("grid-");
grid[Component] = GridComponent; grid[Component] = GridComponent;

View file

@ -11,7 +11,7 @@ import {
} from "util/computed"; } from "util/computed";
import { createLazyProxy } from "util/proxies"; import { createLazyProxy } from "util/proxies";
import { shallowReactive, unref } from "vue"; import { shallowReactive, unref } from "vue";
import { findFeatures, jsx, Replace, setDefault } from "./feature"; import { OptionsFunc, findFeatures, jsx, Replace, setDefault } from "./feature";
export const hotkeys: Record<string, GenericHotkey | undefined> = shallowReactive({}); export const hotkeys: Record<string, GenericHotkey | undefined> = shallowReactive({});
export const HotkeyType = Symbol("Hotkey"); export const HotkeyType = Symbol("Hotkey");
@ -43,10 +43,10 @@ export type GenericHotkey = Replace<
>; >;
export function createHotkey<T extends HotkeyOptions>( export function createHotkey<T extends HotkeyOptions>(
optionsFunc: () => T & ThisType<Hotkey<T>> optionsFunc: OptionsFunc<T, Hotkey<T>, BaseHotkey>
): Hotkey<T> { ): Hotkey<T> {
return createLazyProxy(() => { return createLazyProxy(() => {
const hotkey: T & Partial<BaseHotkey> = optionsFunc(); const hotkey = optionsFunc();
hotkey.type = HotkeyType; hotkey.type = HotkeyType;
processComputable(hotkey as T, "enabled"); processComputable(hotkey as T, "enabled");

View file

@ -2,6 +2,7 @@ import InfoboxComponent from "features/infoboxes/Infobox.vue";
import { import {
CoercableComponent, CoercableComponent,
Component, Component,
OptionsFunc,
GatherProps, GatherProps,
getUniqueID, getUniqueID,
Replace, Replace,
@ -63,12 +64,10 @@ export type GenericInfobox = Replace<
>; >;
export function createInfobox<T extends InfoboxOptions>( export function createInfobox<T extends InfoboxOptions>(
optionsFunc: () => T & ThisType<Infobox<T>> optionsFunc: OptionsFunc<T, Infobox<T>, BaseInfobox>
): Infobox<T> { ): Infobox<T> {
return createLazyProxy(persistent => { return createLazyProxy(persistent => {
// Create temp literally just to avoid explicitly assigning types const infobox = Object.assign(persistent, optionsFunc());
const temp = Object.assign(persistent, optionsFunc());
const infobox: Partial<BaseInfobox> & typeof temp = temp;
infobox.id = getUniqueID("infobox-"); infobox.id = getUniqueID("infobox-");
infobox.type = InfoboxType; infobox.type = InfoboxType;
infobox[Component] = InfoboxComponent; infobox[Component] = InfoboxComponent;

View file

@ -1,5 +1,5 @@
import LinksComponent from "./Links.vue"; import LinksComponent from "./Links.vue";
import { Component, GatherProps, Replace } from "features/feature"; import { Component, OptionsFunc, GatherProps, Replace } from "features/feature";
import { Position } from "game/layers"; import { Position } from "game/layers";
import { import {
Computable, Computable,
@ -44,10 +44,10 @@ export type GenericLinks = Replace<
>; >;
export function createLinks<T extends LinksOptions>( export function createLinks<T extends LinksOptions>(
optionsFunc: (() => T) & ThisType<Links<T>> optionsFunc: OptionsFunc<T, Links<T>, BaseLinks>
): Links<T> { ): Links<T> {
return createLazyProxy(() => { return createLazyProxy(() => {
const links: T & Partial<BaseLinks> = optionsFunc(); const links = optionsFunc();
links.type = LinksType; links.type = LinksType;
links[Component] = LinksComponent; links[Component] = LinksComponent;

View file

@ -2,6 +2,7 @@ import Select from "components/fields/Select.vue";
import { import {
CoercableComponent, CoercableComponent,
Component, Component,
OptionsFunc,
GatherProps, GatherProps,
getUniqueID, getUniqueID,
jsx, jsx,
@ -83,12 +84,10 @@ export type GenericMilestone = Replace<
>; >;
export function createMilestone<T extends MilestoneOptions>( export function createMilestone<T extends MilestoneOptions>(
optionsFunc: () => T & ThisType<Milestone<T>> optionsFunc: OptionsFunc<T, Milestone<T>, BaseMilestone>
): Milestone<T> { ): Milestone<T> {
return createLazyProxy(persistent => { return createLazyProxy(persistent => {
// Create temp literally just to avoid explicitly assigning types const milestone = Object.assign(persistent, optionsFunc());
const temp = Object.assign(persistent, optionsFunc());
const milestone: Partial<BaseMilestone> & typeof temp = temp;
milestone.id = getUniqueID("milestone-"); milestone.id = getUniqueID("milestone-");
milestone.type = MilestoneType; milestone.type = MilestoneType;
milestone[Component] = MilestoneComponent; milestone[Component] = MilestoneComponent;

View file

@ -1,6 +1,13 @@
import ParticlesComponent from "features/particles/Particles.vue"; import ParticlesComponent from "features/particles/Particles.vue";
import { Ref, shallowRef, unref } from "vue"; import { Ref, shallowRef, unref } from "vue";
import { Component, GatherProps, getUniqueID, Replace, StyleValue } from "features/feature"; import {
Component,
OptionsFunc,
GatherProps,
getUniqueID,
Replace,
StyleValue
} from "features/feature";
import { createLazyProxy } from "util/proxies"; import { createLazyProxy } from "util/proxies";
import { Application } from "pixi.js"; import { Application } from "pixi.js";
import { Emitter, EmitterConfigV3, upgradeConfig } from "@pixi/particle-emitter"; import { Emitter, EmitterConfigV3, upgradeConfig } from "@pixi/particle-emitter";
@ -35,10 +42,10 @@ export type Particles<T extends ParticlesOptions> = Replace<
export type GenericParticles = Particles<ParticlesOptions>; export type GenericParticles = Particles<ParticlesOptions>;
export function createParticles<T extends ParticlesOptions>( export function createParticles<T extends ParticlesOptions>(
optionsFunc: () => T & ThisType<Particles<T>> optionsFunc: OptionsFunc<T, Particles<T>, BaseParticles>
): Particles<T> { ): Particles<T> {
return createLazyProxy(() => { return createLazyProxy(() => {
const particles: T & Partial<BaseParticles> = optionsFunc(); const particles = optionsFunc();
particles.id = getUniqueID("particles-"); particles.id = getUniqueID("particles-");
particles.type = ParticlesType; particles.type = ParticlesType;
particles[Component] = ParticlesComponent; particles[Component] = ParticlesComponent;

View file

@ -1,4 +1,4 @@
import { getUniqueID, Replace } from "features/feature"; import { OptionsFunc, getUniqueID, Replace } from "features/feature";
import { globalBus } from "game/events"; import { globalBus } from "game/events";
import { GenericLayer } from "game/layers"; import { GenericLayer } from "game/layers";
import { DefaultValue, Persistent, persistent, PersistentState } from "game/persistence"; import { DefaultValue, Persistent, persistent, PersistentState } from "game/persistence";
@ -31,10 +31,10 @@ export type Reset<T extends ResetOptions> = Replace<
export type GenericReset = Reset<ResetOptions>; export type GenericReset = Reset<ResetOptions>;
export function createReset<T extends ResetOptions>( export function createReset<T extends ResetOptions>(
optionsFunc: () => T & ThisType<Reset<T>> optionsFunc: OptionsFunc<T, Reset<T>, BaseReset>
): Reset<T> { ): Reset<T> {
return createLazyProxy(() => { return createLazyProxy(() => {
const reset: T & Partial<BaseReset> = optionsFunc(); const reset = optionsFunc();
reset.id = getUniqueID("reset-"); reset.id = getUniqueID("reset-");
reset.type = ResetType; reset.type = ResetType;

View file

@ -1,6 +1,7 @@
import { import {
CoercableComponent, CoercableComponent,
Component, Component,
OptionsFunc,
GatherProps, GatherProps,
getUniqueID, getUniqueID,
Replace, Replace,
@ -36,9 +37,11 @@ export type Tab<T extends TabOptions> = Replace<
export type GenericTab = Tab<TabOptions>; export type GenericTab = Tab<TabOptions>;
export function createTab<T extends TabOptions>(optionsFunc: () => T & ThisType<Tab<T>>): Tab<T> { export function createTab<T extends TabOptions>(
optionsFunc: OptionsFunc<T, Tab<T>, BaseTab>
): Tab<T> {
return createLazyProxy(() => { return createLazyProxy(() => {
const tab: T & Partial<BaseTab> = optionsFunc(); const tab = optionsFunc();
tab.id = getUniqueID("tab-"); tab.id = getUniqueID("tab-");
tab.type = TabType; tab.type = TabType;
tab[Component] = TabComponent; tab[Component] = TabComponent;

View file

@ -1,6 +1,7 @@
import { import {
CoercableComponent, CoercableComponent,
Component, Component,
OptionsFunc,
GatherProps, GatherProps,
getUniqueID, getUniqueID,
Replace, Replace,
@ -91,7 +92,7 @@ export type GenericTabFamily = Replace<
export function createTabFamily<T extends TabFamilyOptions>( export function createTabFamily<T extends TabFamilyOptions>(
tabs: Record<string, () => TabButtonOptions>, tabs: Record<string, () => TabButtonOptions>,
optionsFunc: () => T & ThisType<TabFamily<T>> optionsFunc: OptionsFunc<T, TabFamily<T>, BaseTabFamily>
): TabFamily<T> { ): TabFamily<T> {
if (Object.keys(tabs).length === 0) { if (Object.keys(tabs).length === 0) {
console.warn("Cannot create tab family with 0 tabs"); console.warn("Cannot create tab family with 0 tabs");
@ -99,9 +100,7 @@ export function createTabFamily<T extends TabFamilyOptions>(
} }
return createLazyProxy(persistent => { return createLazyProxy(persistent => {
// Create temp literally just to avoid explicitly assigning types const tabFamily = Object.assign(persistent, optionsFunc());
const temp = Object.assign(persistent, optionsFunc());
const tabFamily: Partial<BaseTabFamily> & typeof temp = temp;
tabFamily.id = getUniqueID("tabFamily-"); tabFamily.id = getUniqueID("tabFamily-");
tabFamily.type = TabFamilyType; tabFamily.type = TabFamilyType;

View file

@ -1,6 +1,7 @@
import { import {
CoercableComponent, CoercableComponent,
Component, Component,
OptionsFunc,
GatherProps, GatherProps,
getUniqueID, getUniqueID,
Replace, Replace,
@ -74,11 +75,11 @@ export type GenericTreeNode = Replace<
>; >;
export function createTreeNode<T extends TreeNodeOptions>( export function createTreeNode<T extends TreeNodeOptions>(
optionsFunc: () => T & ThisType<TreeNode<T>> optionsFunc: OptionsFunc<T, TreeNode<T>, BaseTreeNode>
): TreeNode<T> { ): TreeNode<T> {
const forceTooltip = persistent(false); const forceTooltip = persistent(false);
return createLazyProxy(() => { return createLazyProxy(() => {
const treeNode: T & Partial<BaseTreeNode> = optionsFunc(); const treeNode = optionsFunc();
treeNode.id = getUniqueID("treeNode-"); treeNode.id = getUniqueID("treeNode-");
treeNode.type = TreeNodeType; treeNode.type = TreeNodeType;
@ -168,10 +169,10 @@ export type GenericTree = Replace<
>; >;
export function createTree<T extends TreeOptions>( export function createTree<T extends TreeOptions>(
optionsFunc: () => T & ThisType<Tree<T>> optionsFunc: OptionsFunc<T, Tree<T>, BaseTree>
): Tree<T> { ): Tree<T> {
return createLazyProxy(() => { return createLazyProxy(() => {
const tree: T & Partial<BaseTree> = optionsFunc(); const tree = optionsFunc();
tree.id = getUniqueID("tree-"); tree.id = getUniqueID("tree-");
tree.type = TreeType; tree.type = TreeType;
tree[Component] = TreeComponent; tree[Component] = TreeComponent;

View file

@ -2,6 +2,7 @@ import UpgradeComponent from "features/upgrades/Upgrade.vue";
import { import {
CoercableComponent, CoercableComponent,
Component, Component,
OptionsFunc,
findFeatures, findFeatures,
GatherProps, GatherProps,
getUniqueID, getUniqueID,
@ -78,12 +79,10 @@ export type GenericUpgrade = Replace<
>; >;
export function createUpgrade<T extends UpgradeOptions>( export function createUpgrade<T extends UpgradeOptions>(
optionsFunc: () => T & ThisType<Upgrade<T>> optionsFunc: OptionsFunc<T, Upgrade<T>, BaseUpgrade>
): Upgrade<T> { ): Upgrade<T> {
return createLazyProxy(persistent => { return createLazyProxy(persistent => {
// Create temp literally just to avoid explicitly assigning types const upgrade = Object.assign(persistent, optionsFunc());
const temp = Object.assign(persistent, optionsFunc());
const upgrade: Partial<BaseUpgrade> & typeof temp = temp;
upgrade.id = getUniqueID("upgrade-"); upgrade.id = getUniqueID("upgrade-");
upgrade.type = UpgradeType; upgrade.type = UpgradeType;
upgrade[Component] = UpgradeComponent; upgrade[Component] = UpgradeComponent;

View file

@ -1,6 +1,7 @@
import Modal from "components/Modal.vue"; import Modal from "components/Modal.vue";
import { import {
CoercableComponent, CoercableComponent,
OptionsFunc,
jsx, jsx,
JSXFunction, JSXFunction,
Replace, Replace,
@ -104,7 +105,7 @@ export const persistentRefs: Record<string, Set<Persistent>> = {};
export const addingLayers: string[] = []; export const addingLayers: string[] = [];
export function createLayer<T extends LayerOptions>( export function createLayer<T extends LayerOptions>(
id: string, id: string,
optionsFunc: (() => T) & ThisType<BaseLayer> optionsFunc: OptionsFunc<T, BaseLayer, BaseLayer>
): Layer<T> { ): Layer<T> {
return createLazyProxy(() => { return createLazyProxy(() => {
const layer = {} as T & Partial<BaseLayer>; const layer = {} as T & Partial<BaseLayer>;