UNPKG

typedi

Version:

Dependency injection for TypeScript.

45 lines 3.11 kB
import { Token } from '../token.class'; /** * Helper function used in inject decorators to resolve the received identifier to * an eager type when possible or to a lazy type when cyclic dependencies are possibly involved. * * @param typeOrIdentifier a service identifier or a function returning a type acting as service identifier or nothing * @param target the class definition of the target of the decorator * @param propertyName the name of the property in case of a PropertyDecorator * @param index the index of the parameter in the constructor in case of ParameterDecorator */ export function resolveToTypeWrapper(typeOrIdentifier, target, propertyName, index) { /** * ? We want to error out as soon as possible when looking up services to inject, however * ? we cannot determine the type at decorator execution when cyclic dependencies are involved * ? because calling the received `() => MyType` function right away would cause a JS error: * ? "Cannot access 'MyType' before initialization", so we need to execute the function in the handler, * ? when the classes are already created. To overcome this, we use a wrapper: * ? - the lazyType is executed in the handler so we never have a JS error * ? - the eagerType is checked when decorator is running and an error is raised if an unknown type is encountered */ var typeWrapper; /** If requested type is explicitly set via a string ID or token, we set it explicitly. */ if ((typeOrIdentifier && typeof typeOrIdentifier === 'string') || typeOrIdentifier instanceof Token) { typeWrapper = { eagerType: typeOrIdentifier, lazyType: function () { return typeOrIdentifier; } }; } /** If requested type is explicitly set via a () => MyClassType format, we set it explicitly. */ if (typeOrIdentifier && typeof typeOrIdentifier === 'function') { /** We set eagerType to null, preventing the raising of the CannotInjectValueError in decorators. */ typeWrapper = { eagerType: null, lazyType: function () { return typeOrIdentifier(); } }; } /** If no explicit type is set and handler registered for a class property, we need to get the property type. */ if (!typeOrIdentifier && propertyName) { var identifier_1 = Reflect.getMetadata('design:type', target, propertyName); typeWrapper = { eagerType: identifier_1, lazyType: function () { return identifier_1; } }; } /** If no explicit type is set and handler registered for a constructor parameter, we need to get the parameter types. */ if (!typeOrIdentifier && typeof index == 'number' && Number.isInteger(index)) { var paramTypes = Reflect.getMetadata('design:paramtypes', target, propertyName); /** It's not guaranteed, that we find any types for the constructor. */ var identifier_2 = paramTypes === null || paramTypes === void 0 ? void 0 : paramTypes[index]; typeWrapper = { eagerType: identifier_2, lazyType: function () { return identifier_2; } }; } return typeWrapper; } //# sourceMappingURL=resolve-to-type-wrapper.util.js.map