Skip to content

Conversation

@bajtos
Copy link
Member

@bajtos bajtos commented Sep 24, 2018

Implement a concept of deferred type resolution, where the decorator metadata provides a TypeResolver function to obtain the actual type to use. For example:

@property(() => Product

Deferred resolution is a solution for avoiding require() loops that are frequently encountered when defining relations like hasMany + belongsTo.

I have extracted this pull request from #1618, please refer to that pull request to better understand the context of this change and previous discussions.

In #1618, I was advocating against using Type | TypeResolver union. As I was thinking more about other approaches, the impacts on developer experience (LB4 app authors) and how little time we have until 4.0 GA, I decided to continue down the road started by @shimks.

This pull request is related to #1361.

Checklist

  • npm test passes on your machine
  • New tests added or existing tests modified to cover all changes
  • Code conforms with the style guide
  • API Documentation in code was updated
  • Documentation in /docs/site was updated
  • Affected artifact templates in packages/cli were updated
  • Affected example projects in examples/* were updated

@bajtos bajtos added the feature label Sep 24, 2018
@bajtos bajtos added this to the September Milestone milestone Sep 24, 2018
@bajtos bajtos self-assigned this Sep 24, 2018
* Determines whether the given constructor is a custom type or not
* @param ctor Constructor
*/
export function isComplexType(ctor: Function) {
Copy link
Member Author

Choose a reason for hiding this comment

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

Moved to @loopback/repository as isBuiltinType.

});
} else {
Object.assign(propDef, {$ref: `#/definitions/${resolvedType.name}`});
}
Copy link
Member Author

Choose a reason for hiding this comment

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

I re-organized the branches in a different order, that's why the diff looks bigger than the changes actually are.

resolveType(metaProperty.itemType as string | Function)
: resolvedType;

result.definitions[referenceType.name] = propSchema;
Copy link
Member Author

Choose a reason for hiding this comment

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

I added a reverse check + continue, this part is best reviewed with white-space changes ignored. (See "Diff settings" at the top of the page.)

// populating "properties" key
result.properties[p] = metaToJsonProperty(metaProperty);

// handling 'required' metadata
Copy link
Member Author

Choose a reason for hiding this comment

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

Moved here from the bottom of the loop body to allow me to use early continue.

Copy link
Contributor

@b-admike b-admike left a comment

Choose a reason for hiding this comment

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

left some minor comments, but LGTM 👍

expect(isTypeResolver(Boolean)).to.be.false();
});

it('returns false when the arg is Object type', () => {
Copy link
Contributor

Choose a reason for hiding this comment

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

Nitpick: since the logic in these tests is the same, can you create a helper function which takes in the parameter to the isTypeResolver function and creates a test case with the type name as well as the expected result?

Copy link
Member Author

Choose a reason for hiding this comment

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

Creating parameterized test cases is tricky. If done wrong, then test failures don't point to the source code of the individual test case, only to the same helper function. In coercion tests, we found a solution where we intercept errors and append extra stack trace to them in order to preserve location of where the test case was defined.

In this particular case, I think such extra complexity outweighs benefits.

expect(inst.toISOString()).to.equal(A_DATE_STRING);
});

it('supports Date provider', () => {
Copy link
Contributor

Choose a reason for hiding this comment

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

Nitpick: would supports Date resolver be better than provider?

Copy link
Member Author

Choose a reason for hiding this comment

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

Good catch! Will fix.

expect(isBuiltinType(Number)).to.eql(true);
});

it('returns true for String', () => {
Copy link
Contributor

Choose a reason for hiding this comment

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

Nitpick: ditto re organizing the test cases in a clear way, while utilizing a helper function like I mentioned above. With that said, I'm still fine with these explicit tests.

}

/**
* Check if the provided function is a built-in type: a constructor-like
Copy link
Contributor

Choose a reason for hiding this comment

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

Nitpick: can we say built-in type or a constructor-like... instead of using a colon?

Implement a concept of deferred type resolution, where the decorator
metadata provides a TypeResolver function to obtain the actual type
to use. For example:

```ts
@Property(() => Product
```

Deferred resolution is a solution for avoiding require() loops
that are frequently encountered when defining relations like
hasMany + belongsTo.

Co-authored-by: Kyusung Shim <ks1771@naver.com>
@bajtos bajtos force-pushed the feat/property-type-resolver branch from a9f4387 to 023e6d0 Compare September 25, 2018 08:04
@bajtos bajtos merged commit 49454aa into master Sep 25, 2018
@bajtos bajtos deleted the feat/property-type-resolver branch September 25, 2018 08:22
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants