diff --git a/CHANGELOG.md b/CHANGELOG.md index a51bc3683..5ec3f563d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Changed ### Fixed +- Fixed unexpected property access while running planning checks on injected base types. ## [6.1.5] diff --git a/src/planning/reflection_utils.ts b/src/planning/reflection_utils.ts index 5614e54ef..3f50c2ce5 100644 --- a/src/planning/reflection_utils.ts +++ b/src/planning/reflection_utils.ts @@ -3,6 +3,7 @@ import { getTargets } from '@inversifyjs/core'; import * as METADATA_KEY from '../constants/metadata_keys'; import { interfaces } from '../interfaces/interfaces'; +import { getBaseType } from '../utils/get_base_type'; import { getFunctionName } from '../utils/serialization'; import { Metadata } from './metadata'; @@ -17,40 +18,37 @@ function getBaseClassDependencyCount( metadataReader: interfaces.MetadataReader, func: NewableFunction, ): number { - const baseConstructor: NewableFunction = - // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access - Object.getPrototypeOf(func.prototype).constructor as NewableFunction; - if (baseConstructor !== (Object as unknown as NewableFunction)) { - // get targets for base class - - const targets: interfaces.Target[] = getTargets(metadataReader)( - baseConstructor as Newable, - ); - - // get unmanaged metadata - const metadata: interfaces.Metadata[][] = targets.map( - (t: interfaces.Target) => - t.metadata.filter( - (m: interfaces.Metadata) => m.key === METADATA_KEY.UNMANAGED_TAG, - ), - ); - - // Compare the number of constructor arguments with the number of - // unmanaged dependencies unmanaged dependencies are not required - const unmanagedCount: number = ([] as Metadata[]).concat.apply( - [], - metadata, - ).length; - const dependencyCount: number = targets.length - unmanagedCount; - - if (dependencyCount > 0) { - return dependencyCount; - } else { - return getBaseClassDependencyCount(metadataReader, baseConstructor); - } - } else { + const baseConstructor: Newable | undefined = getBaseType(func); + + if (baseConstructor === undefined || baseConstructor === Object) { return 0; } + + // get targets for base class + const targets: interfaces.Target[] = + getTargets(metadataReader)(baseConstructor); + + // get unmanaged metadata + const metadata: interfaces.Metadata[][] = targets.map( + (t: interfaces.Target) => + t.metadata.filter( + (m: interfaces.Metadata) => m.key === METADATA_KEY.UNMANAGED_TAG, + ), + ); + + // Compare the number of constructor arguments with the number of + // unmanaged dependencies unmanaged dependencies are not required + const unmanagedCount: number = ([] as Metadata[]).concat.apply( + [], + metadata, + ).length; + const dependencyCount: number = targets.length - unmanagedCount; + + if (dependencyCount > 0) { + return dependencyCount; + } else { + return getBaseClassDependencyCount(metadataReader, baseConstructor); + } } export { getDependencies, getBaseClassDependencyCount, getFunctionName }; diff --git a/src/utils/get_base_type.ts b/src/utils/get_base_type.ts index 2024eb926..f1ad072ae 100644 --- a/src/utils/get_base_type.ts +++ b/src/utils/get_base_type.ts @@ -1,7 +1,7 @@ import { Newable } from '@inversifyjs/common'; interface Prototype { - constructor: Newable; + constructor?: Newable; } // eslint-disable-next-line @typescript-eslint/no-unsafe-function-type