Skip to content

Commit

Permalink
generic types are now inferable from constructor params
Browse files Browse the repository at this point in the history
  • Loading branch information
xaviergonz committed May 7, 2021
1 parent d7a1d44 commit 9be6e0f
Show file tree
Hide file tree
Showing 5 changed files with 34 additions and 23 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
# Change Log

## 0.58.2

- Generic types are now inferable from the constructor parameters

## 0.58.1

- Fixed an issue where `idProp` on the base was not being picked up by `ExtendedModel`.
Expand Down
2 changes: 1 addition & 1 deletion packages/lib/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "mobx-keystone",
"version": "0.58.1",
"version": "0.58.2",
"description": "A MobX powered state management solution based on data trees with first class support for Typescript, snapshots, patches and much more",
"keywords": [
"mobx",
Expand Down
11 changes: 5 additions & 6 deletions packages/lib/src/modelShared/prop.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52,12 +52,11 @@ export type ModelPropsToData<MP extends ModelProps> = {
}

// we don't use O.Optional anymore since it generates unions too heavy
export type ModelPropsToCreationData<MP extends ModelProps> = O.Pick<
{
[k in keyof MP]?: MP[k]["$creationValueType"]
},
OptionalModelProps<MP>
> &
// also if we use pick over the optional props we will loose the ability
// to infer generics
export type ModelPropsToCreationData<MP extends ModelProps> = {
[k in keyof MP]?: MP[k]["$creationValueType"]
} &
O.Omit<
{
[k in keyof MP]: MP[k]["$creationValueType"]
Expand Down
5 changes: 5 additions & 0 deletions packages/lib/test/model/defaultProps.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,11 @@ test("default props", () => {

bb?: number
bbbb?: number | null

a?: number
aaa?: number | null
b?: number
bbb?: number | null
} & {
a: number
aaa: number | null
Expand Down
35 changes: 19 additions & 16 deletions packages/lib/test/model/subclassing.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -86,11 +86,12 @@ test("subclassing with additional props", () => {
x?: number | null
y?: number | null
z?: number | null
} & Empty & {
a?: number | null
} & {
b: number
}
} & {
a?: number | null
b?: number
} & {
b: number
} & Empty
)

const p2 = new P2({ x: 20, b: 70 })
Expand Down Expand Up @@ -300,11 +301,11 @@ test("three level subclassing", () => {
x?: number | null | undefined
y?: number | null | undefined
z?: number | null | undefined
} & Empty & {
a?: number | null | undefined
} & {
b: number
}
} & {
a?: number | null | undefined
} & { b?: number } & {
b: number
} & Empty
)

const p2 = new P2({ x: 20, b: 70 })
Expand Down Expand Up @@ -697,21 +698,22 @@ test("ExtendedModel should bring static / prototype properties", () => {
test("new pattern for generics", () => {
@model("GenericModel")
class GenericModel<T1, T2> extends Model(<U1, U2>() => ({
v1: prop<U1>(),
v1: prop<U1 | undefined>(),
v2: prop<U2>(),
v3: prop<number>(0),
}))<T1, T2> {}

assert(
_ as ModelData<GenericModel<string, number>>,
_ as { [modelIdKey]: string; v1: string; v2: number; v3: number }
_ as { [modelIdKey]: string; v1: string | undefined; v2: number; v3: number }
)
assert(
_ as ModelData<GenericModel<number, string>>,
_ as { [modelIdKey]: string; v1: number; v2: string; v3: number }
_ as { [modelIdKey]: string; v1: number | undefined; v2: string; v3: number }
)

const s = new GenericModel<string, number>({ v1: "1", v2: 2, v3: 3 })
const s = new GenericModel({ v1: "1", v2: 2, v3: 3 })
assert(s, _ as GenericModel<string, number>)
expect(s.v1).toBe("1")
expect(s.v2).toBe(2)
expect(s.v3).toBe(3)
Expand All @@ -720,11 +722,12 @@ test("new pattern for generics", () => {
class ExtendedGenericModel<T1, T2> extends ExtendedModel(<T1, T2>() => ({
baseModel: modelClass<GenericModel<T1, T2>>(GenericModel),
props: {
v4: prop<T2>(),
v4: prop<T2 | undefined>(),
},
}))<T1, T2> {}

const e = new ExtendedGenericModel<string, number>({ v1: "1", v2: 2, v3: 3, v4: 4 })
const e = new ExtendedGenericModel({ v1: "1", v2: 2, v3: 3, v4: 4 })
assert(e, _ as ExtendedGenericModel<string, number>)
expect(e.v1).toBe("1")
expect(e.v2).toBe(2)
expect(e.v3).toBe(3)
Expand Down

0 comments on commit 9be6e0f

Please sign in to comment.