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 type definitions for PersistedModel API #1599

Merged
merged 2 commits into from Jul 2, 2018
Merged

Fix type definitions for PersistedModel API #1599

merged 2 commits into from Jul 2, 2018

Conversation

bajtos
Copy link
Member

@bajtos bajtos commented Jun 28, 2018

  • Callback's first argument is an optional Error now. Was: required any.

  • PersistedModel methods return PersistedModel now. Before this change, methods were returning PersistedData (PersistedModel | AnyObject). The problem with AnyObject is that it does not contain any PersistedModel instance data and cannot be assigned to functions expecting Partial<PersistedModel>. As a result, consumers of this API were forced to either cast the result to PersistedModel (which feels wrong) or deal with the AnyObject case (which never happen at runtime).

  • Fix definition of ModelData<T> to T | Partial<T>. Before this change, ModelData allowed any values not related to the actual model at all, for example arrays.

These problems were discovered while working on loopbackio/loopback-next#1475. The fixes presented in this pull request seem to be backwards compatible, at least as far as loopback-next tests are concerned.

Callback's first argument is an optional Error now. Was: required `any`.

PersistedModel methods return `PersistedModel` now. Before this change,
methods were returning `PersistedData` (`PersistedModel | AnyObject`).
The problem with `AnyObject` is that it does not contain any
`PersistedModel` instance data and cannot be assigned to functions
expecting `Partial<PersistedModel>`. As a result, consumers of this API
were forced to either cast the result to `PersistedModel` (which feels
wrong) or deal with the `AnyObject` case (which never happen at
runtime).

Fix definition of `ModelData<T>` to `T | Partial<T>`. Before this
change, `ModelData` allowed any values not related to the actual
model at all, for example arrays.
@bajtos bajtos requested review from raymondfeng and a team June 28, 2018 11:10
@bajtos bajtos self-assigned this Jun 28, 2018
@@ -18,7 +18,7 @@ export type Options = AnyObject<any>;
/**
* Type alias for Node.js callback functions
*/
export type Callback<T = any> = (err: any, result?: T) => void;
export type Callback<T = any> = (err?: Error | null, result?: T) => void;
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Enable the following usage patterns:

  • callback()
  • callback(null)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shouldn't it be err?: any - AFAIK normally any value passed to first parameter that's not null / undefined means an error. So ... for example, I can pass a string into the Callback?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Node.js does allow the error parameter to be any.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fair enough, I'll change it to err?: any.

types/model.d.ts Outdated
@@ -246,4 +246,4 @@ export declare class ModelBuilder extends EventEmitter {
* Union export type for model instance or plain object representing the model
* instance
*/
export type ModelData<T extends ModelBase = ModelBase> = T | AnyObject;
export type ModelData<T extends ModelBase = ModelBase> = T | Partial<T>;
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Strangely enough, AnyObject allows arbitrary values not related to ModelBase at all, for example an array. This is a problem in PersistedModel API, where the data argument of methods like create or upsert suddenly allows callers to provide an array, despite the fact that these methods don't support batch mode.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We probably should introduce a DeepPartial as follows. It's used in TypeORM too.

export type DeepPartial<T> = { [P in keyof T]?: DeepPartial<T[P]>; };

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

wouldn't T | Partial<T> be the same as Partial<T>?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We probably should introduce a DeepPartial as follows. It's used in TypeORM too.

Will do.

wouldn't T | Partial be the same as Partial?

From compiler's point of view, I think it's the same, because T can be assigned to Partial<T>. From documentation perspective, I feel T | Partial<T> is communicating the intent better.

): PromiseOrVoid<PersistedModel>;

static create(
data: PersistedData[],
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add an overload for batch create mode, where an array of data objects is accepted and the method returns an array of model instances created.

@bajtos
Copy link
Member Author

bajtos commented Jun 29, 2018

@raymondfeng @virkt25 @jannyHou Thank you for the feedback, I have addressed your comments in 6f3675b. LGTY now?

@bajtos bajtos merged commit 3ac18e4 into master Jul 2, 2018
@bajtos bajtos deleted the fix/typings branch July 2, 2018 07:00
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

5 participants