From b2937b16c37d26dcdc55a478ada14117ec589f6b Mon Sep 17 00:00:00 2001 From: Alex Rickabaugh Date: Fri, 7 Jun 2019 10:32:06 -0700 Subject: [PATCH] fix(ivy): distinguish inherited injectable defs by token (#30855) In older browsers such as IE10, inheritance of static properties on class types is implemented by copying the properties. This makes hasOwnProperty unreliable for checking if a static property is defined directly on a class or is inherited. This causes problems when trying to read the ngInjectableDef properties of inherited services, as in IE10 even inherited definitions will appear to be local. Instead, the 'token' property on ngInjectableDef can be leveraged to detect when a definition is read which doesn't belong to the type itself. PR Close #30855 --- packages/core/src/di/interface/defs.ts | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/packages/core/src/di/interface/defs.ts b/packages/core/src/di/interface/defs.ts index 724dcb2c5b..55e76bb804 100644 --- a/packages/core/src/di/interface/defs.ts +++ b/packages/core/src/di/interface/defs.ts @@ -190,7 +190,15 @@ export function ɵɵdefineInjector(options: {factory: () => any, providers?: any * @param type A type which may have its own (non-inherited) `ngInjectableDef`. */ export function getInjectableDef(type: any): ɵɵInjectableDef|null { - return type && type.hasOwnProperty(NG_INJECTABLE_DEF) ? type[NG_INJECTABLE_DEF] : null; + const def = type[NG_INJECTABLE_DEF] as ɵɵInjectableDef; + // The definition read above may come from a base class. `hasOwnProperty` is not sufficient to + // distinguish this case, as in older browsers (e.g. IE10) static property inheritance is + // implemented by copying the properties. + // + // Instead, the ngInjectableDef's token is compared to the type, and if they don't match then the + // property was not defined directly on the type itself, and was likely inherited. The definition + // is only returned if the type matches the def.token. + return def && def.token === type ? def : null; } /**