Skip to content

lib Fix Part 3/6 – Object related methods #50451

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 6 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions src/harness/fourslashInterfaceImpl.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1192,6 +1192,7 @@ export namespace Completion {
typeEntry("Partial"),
typeEntry("Required"),
typeEntry("Readonly"),
typeEntry("Writable"),
typeEntry("Pick"),
typeEntry("Record"),
typeEntry("Exclude"),
Expand Down
21 changes: 14 additions & 7 deletions src/lib/es2015.core.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -257,13 +257,20 @@ interface NumberConstructor {
}

interface ObjectConstructor {
/**
* Copy the values of all of the enumerable own properties from one or more source objects to a
* target object. Returns the target object.
* @param target The target object to copy to.
*/
assign<T extends {}>(target: T): T;

/**
* Copy the values of all of the enumerable own properties from one or more source objects to a
* target object. Returns the target object.
* @param target The target object to copy to.
* @param source The source object from which to copy properties.
*/
assign<T extends {}, U>(target: T, source: U): T & U;
assign<T extends {}, U>(target: T, source: U): T & Writable<U>;

/**
* Copy the values of all of the enumerable own properties from one or more source objects to a
Expand All @@ -272,7 +279,7 @@ interface ObjectConstructor {
* @param source1 The first source object from which to copy properties.
* @param source2 The second source object from which to copy properties.
*/
assign<T extends {}, U, V>(target: T, source1: U, source2: V): T & U & V;
assign<T extends {}, U, V>(target: T, source1: U, source2: V): T & Writable<U> & Writable<V>;

/**
* Copy the values of all of the enumerable own properties from one or more source objects to a
Expand All @@ -282,21 +289,21 @@ interface ObjectConstructor {
* @param source2 The second source object from which to copy properties.
* @param source3 The third source object from which to copy properties.
*/
assign<T extends {}, U, V, W>(target: T, source1: U, source2: V, source3: W): T & U & V & W;
assign<T extends {}, U, V, W>(target: T, source1: U, source2: V, source3: W): T & Writable<U> & Writable<V> & Writable<W>;

/**
* Copy the values of all of the enumerable own properties from one or more source objects to a
* target object. Returns the target object.
* @param target The target object to copy to.
* @param sources One or more source objects from which to copy properties
* @param sources One or more source objects from which to copy properties.
*/
assign(target: object, ...sources: any[]): any;
assign(target: {}, ...sources: any[]): any;

/**
* Returns an array of all symbol properties found directly on object o.
* @param o Object to retrieve the symbols from.
*/
getOwnPropertySymbols(o: any): symbol[];
getOwnPropertySymbols(o: {}): symbol[];

/**
* Returns the names of the enumerable string properties and methods of an object.
Expand All @@ -316,7 +323,7 @@ interface ObjectConstructor {
* @param o The object to change its prototype.
* @param proto The value of the new prototype or null.
*/
setPrototypeOf(o: any, proto: object | null): any;
setPrototypeOf(o: {}, proto: object | null): any;
}

interface ReadonlyArray<T> {
Expand Down
2 changes: 1 addition & 1 deletion src/lib/es2017.object.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,5 +27,5 @@ interface ObjectConstructor {
* Returns an object containing all own property descriptors of an object
* @param o Object that contains the properties and methods. This can be an object that you created or an existing Document Object Model (DOM) object.
*/
getOwnPropertyDescriptors<T>(o: T): {[P in keyof T]: TypedPropertyDescriptor<T[P]>} & { [x: string]: PropertyDescriptor };
getOwnPropertyDescriptors<T extends {}>(o: T): { [P in keyof T]: TypedPropertyDescriptor<T[P]> } & PropertyDescriptorMap;
}
2 changes: 1 addition & 1 deletion src/lib/es2019.object.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ interface ObjectConstructor {
* Returns an object created by key-value entries for properties and methods
* @param entries An iterable object that contains key-value entries for properties and methods.
*/
fromEntries<T = any>(entries: Iterable<readonly [PropertyKey, T]>): { [k: string]: T };
fromEntries<T = any>(entries: Iterable<readonly [PropertyKey, T]>): { [k: PropertyKey]: T };

/**
* Returns an object created by key-value entries for properties and methods
Expand Down
2 changes: 1 addition & 1 deletion src/lib/es2022.object.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,5 @@ interface ObjectConstructor {
* @param o An object.
* @param v A property name.
*/
hasOwn(o: object, v: PropertyKey): boolean;
hasOwn(o: {}, v: PropertyKey): boolean;
}
43 changes: 34 additions & 9 deletions src/lib/es5.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -146,22 +146,22 @@ interface ObjectConstructor {
* Returns the prototype of an object.
* @param o The object that references the prototype.
*/
getPrototypeOf(o: any): any;
getPrototypeOf(o: {}): any;

/**
* Gets the own property descriptor of the specified object.
* An own property descriptor is one that is defined directly on the object and is not inherited from the object's prototype.
* @param o Object that contains the property.
* @param p Name of the property.
*/
getOwnPropertyDescriptor(o: any, p: PropertyKey): PropertyDescriptor | undefined;
getOwnPropertyDescriptor(o: {}, p: PropertyKey): PropertyDescriptor | undefined;

/**
* Returns the names of the own properties of an object. The own properties of an object are those that are defined directly
* on that object, and are not inherited from the object's prototype. The properties of an object include both fields (objects) and functions.
* @param o Object that contains the own properties.
*/
getOwnPropertyNames(o: any): string[];
getOwnPropertyNames(o: {}): string[];

/**
* Creates an object that has the specified prototype or that has null prototype.
Expand All @@ -182,14 +182,14 @@ interface ObjectConstructor {
* @param p The property name.
* @param attributes Descriptor for the property. It can be for a data property or an accessor property.
*/
defineProperty<T>(o: T, p: PropertyKey, attributes: PropertyDescriptor & ThisType<any>): T;
defineProperty<T extends object>(o: T, p: PropertyKey, attributes: PropertyDescriptor & ThisType<any>): T;

/**
* Adds one or more properties to an object, and/or modifies attributes of existing properties.
* @param o Object on which to add or modify the properties. This can be a native JavaScript object or a DOM object.
* @param properties JavaScript object that contains one or more descriptor objects. Each descriptor object describes a data property or an accessor property.
*/
defineProperties<T>(o: T, properties: PropertyDescriptorMap & ThisType<any>): T;
defineProperties<T extends object>(o: T, properties: PropertyDescriptorMap & ThisType<any>): T;

/**
* Prevents the modification of attributes of existing properties, and prevents the addition of new properties.
Expand All @@ -207,7 +207,7 @@ interface ObjectConstructor {
* Prevents the modification of existing property attributes and values, and prevents the addition of new properties.
* @param o Object on which to lock the attributes.
*/
freeze<T extends {[idx: string]: U | null | undefined | object}, U extends string | bigint | number | boolean | symbol>(o: T): Readonly<T>;
freeze<T extends { [idx: string]: U | null | undefined | object }, U extends string | bigint | number | boolean | symbol>(o: T): Readonly<T>;

/**
* Prevents the modification of existing property attributes and values, and prevents the addition of new properties.
Expand All @@ -225,19 +225,37 @@ interface ObjectConstructor {
* Returns true if existing property attributes cannot be modified in an object and new properties cannot be added to the object.
* @param o Object to test.
*/
isSealed(o: any): boolean;
isSealed(o: object): boolean;

/**
* Returns true if existing property attributes cannot be modified in an object and new properties cannot be added to the object.
* @param o Object to test.
*/
isSealed(o: any): true;

/**
* Returns true if existing property attributes and values cannot be modified in an object, and new properties cannot be added to the object.
* @param o Object to test.
*/
isFrozen(o: object): boolean;

/**
* Returns true if existing property attributes and values cannot be modified in an object, and new properties cannot be added to the object.
* @param o Object to test.
*/
isFrozen(o: any): boolean;
isFrozen(o: any): true;

/**
* Returns a value that indicates whether new properties can be added to an object.
* @param o Object to test.
*/
isExtensible(o: any): boolean;
isExtensible(o: object): boolean;

/**
* Returns a value that indicates whether new properties can be added to an object.
* @param o Object to test.
*/
isExtensible(o: any): false;
Comment on lines +228 to +258
Copy link
Contributor

Choose a reason for hiding this comment

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

These changes are not actually correct, as object is a subtype of any, and thus, a variable that is a union of object and non‑object will cause the second overload to be selected.


/**
* Returns the names of the enumerable string properties and methods of an object.
Expand Down Expand Up @@ -1555,6 +1573,13 @@ type Readonly<T> = {
readonly [P in keyof T]: T[P];
};

/**
* Make all properties in T writable
*/
type Writable<T> = {
-readonly [P in keyof T]: T[P];
};

/**
* From T, pick a set of properties whose keys are in the union K
*/
Expand Down
2 changes: 1 addition & 1 deletion src/testRunner/parallel/worker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -196,7 +196,7 @@ export function start() {
newSuite.addTest(test);
root.addSuite(newSuite);
Object.setPrototypeOf(newSuite.ctx, root.ctx);
Object.setPrototypeOf(test.ctx, root.ctx);
Object.setPrototypeOf(test.ctx!, root.ctx);
test.parent = newSuite;
suite = newSuite;
}
Expand Down
40 changes: 20 additions & 20 deletions tests/baselines/reference/checkExportsObjectAssignProperty.types
Original file line number Diff line number Diff line change
Expand Up @@ -176,9 +176,9 @@ m2.setonlyAccessor = 0;
=== tests/cases/conformance/jsdoc/mod1.js ===
Object.defineProperty(exports, "thing", { value: 42, writable: true });
>Object.defineProperty(exports, "thing", { value: 42, writable: true }) : typeof import("tests/cases/conformance/jsdoc/mod1")
>Object.defineProperty : <T>(o: T, p: PropertyKey, attributes: PropertyDescriptor & ThisType<any>) => T
>Object.defineProperty : <T extends object>(o: T, p: PropertyKey, attributes: PropertyDescriptor & ThisType<any>) => T
>Object : ObjectConstructor
>defineProperty : <T>(o: T, p: PropertyKey, attributes: PropertyDescriptor & ThisType<any>) => T
>defineProperty : <T extends object>(o: T, p: PropertyKey, attributes: PropertyDescriptor & ThisType<any>) => T
>exports : typeof import("tests/cases/conformance/jsdoc/mod1")
>"thing" : "thing"
>{ value: 42, writable: true } : { value: number; writable: true; }
Expand All @@ -189,9 +189,9 @@ Object.defineProperty(exports, "thing", { value: 42, writable: true });

Object.defineProperty(exports, "readonlyProp", { value: "Smith", writable: false });
>Object.defineProperty(exports, "readonlyProp", { value: "Smith", writable: false }) : typeof import("tests/cases/conformance/jsdoc/mod1")
>Object.defineProperty : <T>(o: T, p: PropertyKey, attributes: PropertyDescriptor & ThisType<any>) => T
>Object.defineProperty : <T extends object>(o: T, p: PropertyKey, attributes: PropertyDescriptor & ThisType<any>) => T
>Object : ObjectConstructor
>defineProperty : <T>(o: T, p: PropertyKey, attributes: PropertyDescriptor & ThisType<any>) => T
>defineProperty : <T extends object>(o: T, p: PropertyKey, attributes: PropertyDescriptor & ThisType<any>) => T
>exports : typeof import("tests/cases/conformance/jsdoc/mod1")
>"readonlyProp" : "readonlyProp"
>{ value: "Smith", writable: false } : { value: string; writable: false; }
Expand All @@ -202,9 +202,9 @@ Object.defineProperty(exports, "readonlyProp", { value: "Smith", writable: false

Object.defineProperty(exports, "rwAccessors", { get() { return 98122 }, set(_) { /*ignore*/ } });
>Object.defineProperty(exports, "rwAccessors", { get() { return 98122 }, set(_) { /*ignore*/ } }) : typeof import("tests/cases/conformance/jsdoc/mod1")
>Object.defineProperty : <T>(o: T, p: PropertyKey, attributes: PropertyDescriptor & ThisType<any>) => T
>Object.defineProperty : <T extends object>(o: T, p: PropertyKey, attributes: PropertyDescriptor & ThisType<any>) => T
>Object : ObjectConstructor
>defineProperty : <T>(o: T, p: PropertyKey, attributes: PropertyDescriptor & ThisType<any>) => T
>defineProperty : <T extends object>(o: T, p: PropertyKey, attributes: PropertyDescriptor & ThisType<any>) => T
>exports : typeof import("tests/cases/conformance/jsdoc/mod1")
>"rwAccessors" : "rwAccessors"
>{ get() { return 98122 }, set(_) { /*ignore*/ } } : { get(): number; set(_: any): void; }
Expand All @@ -215,9 +215,9 @@ Object.defineProperty(exports, "rwAccessors", { get() { return 98122 }, set(_) {

Object.defineProperty(exports, "readonlyAccessor", { get() { return 21.75 } });
>Object.defineProperty(exports, "readonlyAccessor", { get() { return 21.75 } }) : typeof import("tests/cases/conformance/jsdoc/mod1")
>Object.defineProperty : <T>(o: T, p: PropertyKey, attributes: PropertyDescriptor & ThisType<any>) => T
>Object.defineProperty : <T extends object>(o: T, p: PropertyKey, attributes: PropertyDescriptor & ThisType<any>) => T
>Object : ObjectConstructor
>defineProperty : <T>(o: T, p: PropertyKey, attributes: PropertyDescriptor & ThisType<any>) => T
>defineProperty : <T extends object>(o: T, p: PropertyKey, attributes: PropertyDescriptor & ThisType<any>) => T
>exports : typeof import("tests/cases/conformance/jsdoc/mod1")
>"readonlyAccessor" : "readonlyAccessor"
>{ get() { return 21.75 } } : { get(): number; }
Expand All @@ -226,9 +226,9 @@ Object.defineProperty(exports, "readonlyAccessor", { get() { return 21.75 } });

Object.defineProperty(exports, "setonlyAccessor", {
>Object.defineProperty(exports, "setonlyAccessor", { /** @param {string} str */ set(str) { this.rwAccessors = Number(str) }}) : typeof import("tests/cases/conformance/jsdoc/mod1")
>Object.defineProperty : <T>(o: T, p: PropertyKey, attributes: PropertyDescriptor & ThisType<any>) => T
>Object.defineProperty : <T extends object>(o: T, p: PropertyKey, attributes: PropertyDescriptor & ThisType<any>) => T
>Object : ObjectConstructor
>defineProperty : <T>(o: T, p: PropertyKey, attributes: PropertyDescriptor & ThisType<any>) => T
>defineProperty : <T extends object>(o: T, p: PropertyKey, attributes: PropertyDescriptor & ThisType<any>) => T
>exports : typeof import("tests/cases/conformance/jsdoc/mod1")
>"setonlyAccessor" : "setonlyAccessor"
>{ /** @param {string} str */ set(str) { this.rwAccessors = Number(str) }} : { set(str: string): void; }
Expand All @@ -252,9 +252,9 @@ Object.defineProperty(exports, "setonlyAccessor", {
=== tests/cases/conformance/jsdoc/mod2.js ===
Object.defineProperty(module.exports, "thing", { value: "yes", writable: true });
>Object.defineProperty(module.exports, "thing", { value: "yes", writable: true }) : typeof module.exports
>Object.defineProperty : <T>(o: T, p: PropertyKey, attributes: PropertyDescriptor & ThisType<any>) => T
>Object.defineProperty : <T extends object>(o: T, p: PropertyKey, attributes: PropertyDescriptor & ThisType<any>) => T
>Object : ObjectConstructor
>defineProperty : <T>(o: T, p: PropertyKey, attributes: PropertyDescriptor & ThisType<any>) => T
>defineProperty : <T extends object>(o: T, p: PropertyKey, attributes: PropertyDescriptor & ThisType<any>) => T
>module.exports : typeof module.exports
>module : { exports: typeof module.exports; }
>exports : typeof module.exports
Expand All @@ -267,9 +267,9 @@ Object.defineProperty(module.exports, "thing", { value: "yes", writable: true })

Object.defineProperty(module.exports, "readonlyProp", { value: "Smith", writable: false });
>Object.defineProperty(module.exports, "readonlyProp", { value: "Smith", writable: false }) : typeof module.exports
>Object.defineProperty : <T>(o: T, p: PropertyKey, attributes: PropertyDescriptor & ThisType<any>) => T
>Object.defineProperty : <T extends object>(o: T, p: PropertyKey, attributes: PropertyDescriptor & ThisType<any>) => T
>Object : ObjectConstructor
>defineProperty : <T>(o: T, p: PropertyKey, attributes: PropertyDescriptor & ThisType<any>) => T
>defineProperty : <T extends object>(o: T, p: PropertyKey, attributes: PropertyDescriptor & ThisType<any>) => T
>module.exports : typeof module.exports
>module : { exports: typeof module.exports; }
>exports : typeof module.exports
Expand All @@ -282,9 +282,9 @@ Object.defineProperty(module.exports, "readonlyProp", { value: "Smith", writable

Object.defineProperty(module.exports, "rwAccessors", { get() { return 98122 }, set(_) { /*ignore*/ } });
>Object.defineProperty(module.exports, "rwAccessors", { get() { return 98122 }, set(_) { /*ignore*/ } }) : typeof module.exports
>Object.defineProperty : <T>(o: T, p: PropertyKey, attributes: PropertyDescriptor & ThisType<any>) => T
>Object.defineProperty : <T extends object>(o: T, p: PropertyKey, attributes: PropertyDescriptor & ThisType<any>) => T
>Object : ObjectConstructor
>defineProperty : <T>(o: T, p: PropertyKey, attributes: PropertyDescriptor & ThisType<any>) => T
>defineProperty : <T extends object>(o: T, p: PropertyKey, attributes: PropertyDescriptor & ThisType<any>) => T
>module.exports : typeof module.exports
>module : { exports: typeof module.exports; }
>exports : typeof module.exports
Expand All @@ -297,9 +297,9 @@ Object.defineProperty(module.exports, "rwAccessors", { get() { return 98122 }, s

Object.defineProperty(module.exports, "readonlyAccessor", { get() { return 21.75 } });
>Object.defineProperty(module.exports, "readonlyAccessor", { get() { return 21.75 } }) : typeof module.exports
>Object.defineProperty : <T>(o: T, p: PropertyKey, attributes: PropertyDescriptor & ThisType<any>) => T
>Object.defineProperty : <T extends object>(o: T, p: PropertyKey, attributes: PropertyDescriptor & ThisType<any>) => T
>Object : ObjectConstructor
>defineProperty : <T>(o: T, p: PropertyKey, attributes: PropertyDescriptor & ThisType<any>) => T
>defineProperty : <T extends object>(o: T, p: PropertyKey, attributes: PropertyDescriptor & ThisType<any>) => T
>module.exports : typeof module.exports
>module : { exports: typeof module.exports; }
>exports : typeof module.exports
Expand All @@ -310,9 +310,9 @@ Object.defineProperty(module.exports, "readonlyAccessor", { get() { return 21.75

Object.defineProperty(module.exports, "setonlyAccessor", {
>Object.defineProperty(module.exports, "setonlyAccessor", { /** @param {string} str */ set(str) { this.rwAccessors = Number(str) }}) : typeof module.exports
>Object.defineProperty : <T>(o: T, p: PropertyKey, attributes: PropertyDescriptor & ThisType<any>) => T
>Object.defineProperty : <T extends object>(o: T, p: PropertyKey, attributes: PropertyDescriptor & ThisType<any>) => T
>Object : ObjectConstructor
>defineProperty : <T>(o: T, p: PropertyKey, attributes: PropertyDescriptor & ThisType<any>) => T
>defineProperty : <T extends object>(o: T, p: PropertyKey, attributes: PropertyDescriptor & ThisType<any>) => T
>module.exports : typeof module.exports
>module : { exports: typeof module.exports; }
>exports : typeof module.exports
Expand Down
Loading