diff --git a/packages/zone.js/lib/browser/define-property.ts b/packages/zone.js/lib/browser/define-property.ts index f7161dc9119d..6736e210c966 100644 --- a/packages/zone.js/lib/browser/define-property.ts +++ b/packages/zone.js/lib/browser/define-property.ts @@ -35,10 +35,17 @@ export function propertyPatch() { return _tryDefineProperty(obj, prop, desc, originalConfigurableFlag); }; - Object.defineProperties = function(obj, props) { + Object.defineProperties = function(obj: T, props: PropertyDescriptorMap&ThisType&{ + [s: symbol]: PropertyDescriptor; + }): T { Object.keys(props).forEach(function(prop) { Object.defineProperty(obj, prop, props[prop]); }); + if (Object.getOwnPropertySymbols) { + for (const sym of Object.getOwnPropertySymbols(props)) { + Object.defineProperty(obj, sym, props[sym]); + } + } return obj; }; diff --git a/packages/zone.js/test/browser/define-property.spec.ts b/packages/zone.js/test/browser/define-property.spec.ts index 13818f72975a..2ca2531dcddf 100644 --- a/packages/zone.js/test/browser/define-property.spec.ts +++ b/packages/zone.js/test/browser/define-property.spec.ts @@ -37,3 +37,64 @@ describe('defineProperty', function() { expect((obj as any).prop).toBeFalsy(); }); }); + +describe('defineProperties', () => { + it('should set string props', () => { + const obj: any = {}; + Object.defineProperties(obj, { + 'property1': {value: true, writable: true, enumerable: true}, + 'property2': {value: 'Hello', writable: false, enumerable: true}, + 'property3': { + enumerable: true, + get: () => { + return obj.p3 + }, + set: (val: string) => obj.p3 = val + }, + 'property4': {enumerable: false, writable: true, value: 'hidden'} + }); + expect(Object.keys(obj).sort()).toEqual(['property1', 'property2', 'property3']); + expect(obj.property1).toBeTrue(); + expect(obj.property2).toEqual('Hello'); + expect(obj.property3).toBeUndefined(); + expect(obj.property4).toEqual('hidden'); + obj.property1 = false; + expect(obj.property1).toBeFalse(); + expect(() => obj.property2 = 'new Hello').toThrow(); + obj.property3 = 'property3'; + expect(obj.property3).toEqual('property3'); + obj.property4 = 'property4'; + expect(obj.property4).toEqual('property4'); + }); + it('should set symbol props', () => { + let a = Symbol(); + let b = Symbol(); + const obj: any = {}; + Object.defineProperties(obj, { + [a]: {value: true, writable: true}, + [b]: {get: () => obj.b1, set: (val: string) => obj.b1 = val} + }); + expect(Object.keys(obj)).toEqual([]); + expect(obj[a]).toBeTrue(); + expect(obj[b]).toBeUndefined(); + obj[a] = false; + expect(obj[a]).toBeFalse(); + obj[b] = 'b1'; + expect(obj[b]).toEqual('b1'); + }); + it('should set string and symbol props', () => { + let a = Symbol(); + const obj: any = {}; + Object.defineProperties(obj, { + [a]: {value: true, writable: true}, + 'property1': {value: true, writable: true, enumerable: true}, + }); + expect(Object.keys(obj)).toEqual(['property1']); + expect(obj.property1).toBeTrue(); + expect(obj[a]).toBeTrue(); + obj.property1 = false; + expect(obj.property1).toBeFalse(); + obj[a] = false; + expect(obj[a]).toBeFalse(); + }); +});