Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix types on createReadOnly option of snapshotted views #106

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 32 additions & 3 deletions spec/types.spec.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,19 @@
/* eslint-disable @typescript-eslint/consistent-type-imports */
import type { Has, IsExact } from "conditional-type-checks";
import { assert } from "conditional-type-checks";
import { SnapshotIn, TypesForModelPropsDeclaration, action, register } from "../src";
import { IMaybeNullType, INodeModelType, IOptionalType, ISimpleType, types } from "../src";
import {
ClassModel,
IMaybeNullType,
INodeModelType,
IOptionalType,
ISimpleType,
SnapshotIn,
TypesForModelPropsDeclaration,
action,
register,
snapshottedView,
types,
} from "../src";
import { NamedThingClass, TestClassModel } from "./fixtures/TestClassModel";
import { NamedThing, TestModel } from "./fixtures/TestModel";

Expand Down Expand Up @@ -61,7 +72,7 @@ describe("SnapshotIn", () => {
return "hello";
}
@action
mixinAction(value: string) {
mixinAction(_value: string) {
// empty
}
}
Expand All @@ -77,4 +88,22 @@ describe("SnapshotIn", () => {
assert<IsExact<Actual["optional"], string | undefined>>(true);
assert<Has<keyof Actual, "mixinView">>(false);
});

test("works on class models with snapshotted views", () => {
@register
class DataContainer extends ClassModel({ id: types.identifier }) {}

@register
class DataMap extends ClassModel({ stuff: types.map(DataContainer) }) {}

@register
class _SnapshottedViewClass extends TestClassModel {
@snapshottedView<typeof DataMap>({
createReadOnly: (value) => DataMap.createReadOnly(value),
})
get test() {
return DataMap.createReadOnly();
}
}
});
});
17 changes: 10 additions & 7 deletions src/class-model.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
import "reflect-metadata";

import memoize from "lodash.memoize";
import type { Instance, IModelType as MSTIModelType, ModelActions } from "mobx-state-tree";
import { comparer, reaction, type IReactionDisposer } from "mobx";
import type { IModelType as MSTIModelType, ModelActions } from "mobx-state-tree";
import { types as mstTypes } from "mobx-state-tree";
import { RegistrationError } from "./errors";
import { InstantiatorBuilder } from "./fast-instantiator";
import { FastGetBuilder } from "./fast-getter";
import { InstantiatorBuilder } from "./fast-instantiator";
import { defaultThrowAction, mstPropsFromQuickProps, propsFromModelPropsDeclaration } from "./model";
import { getSnapshot } from "./snapshot";
import {
$context,
$identifier,
Expand All @@ -26,13 +28,13 @@ import type {
IAnyType,
IClassModelType,
IStateTreeNode,
Instance,
ModelPropertiesDeclaration,
ModelViews,
SnapshotIn,
TypesForModelPropsDeclaration,
} from "./types";
import { cyrb53 } from "./utils";
import { comparer, reaction, type IReactionDisposer } from "mobx";
import { getSnapshot } from "./snapshot";

/** @internal */
type ActionMetadata = {
Expand All @@ -42,12 +44,12 @@ type ActionMetadata = {
};

/** Options that configure a snapshotted view */
export interface SnapshottedViewOptions<V, T extends IAnyClassModelType> {
export interface SnapshottedViewOptions<ViewReturnT, ParentNodeT extends IAnyClassModelType> {
/** A function for converting a stored value in the snapshot back to the rich type for the view to return */
createReadOnly?: (value: V | undefined, node: Instance<T>) => V | undefined;
createReadOnly?: (value: SnapshotIn<ViewReturnT> | undefined, node: Instance<ParentNodeT>) => Instance<ViewReturnT> | undefined;

/** A function for converting the view value to a snapshot value */
createSnapshot?: (value: V) => any;
createSnapshot?: (value: ViewReturnT) => any;

/** A function that will be called when the view's reaction throws an error. */
onError?: (error: any) => void;
Expand All @@ -74,6 +76,7 @@ export type VolatileMetadata = {
};

type VolatileInitializer<T> = (instance: T) => Record<string, any>;

/** @internal */
export type PropertyMetadata = ActionMetadata | ViewMetadata | SnapshottedViewMetadata | VolatileMetadata;

Expand Down
Loading