Skip to content

Way of specifying non-enumerable properties #9726

Open
@tinganho

Description

@tinganho

Object assign is defined like below in TS:

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.
      * @param source The source object from which to copy properties.
      */
    assign<T, U>(target: T, source: U): T & U;
}

Though from MDN it is only copying members that are enumerable:

The Object.assign() method is used to copy the values of all enumerable own properties from one or more source objects to a target object. It will return the target object.

So if U above has non-enumerable members, TS will copy them anyway. This is slightly incorrect and unsafe.

One issue I recently ran into was

const selection = Object.assign({}, window.getSelection());

I was assuming I was copying all members of the Selection object to {}:

interface Selection {
    readonly anchorNode: Node;
    readonly anchorOffset: number;
    // etc ...
}

declare var Selection: {
    prototype: Selection;
    new(): Selection;
}

Though it didn't copy any members at all, because the Selection object only contains non-enumerable members.

Proposal

Mark properties as non-enumerable

interface Selection {
    readonly nonenum anchorNode: Node;
    readonly nonenum anchorOffset: number;
    // etc ...
}

And have an operator to get the only "enum side" of a type:

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.
      * @param source The source object from which to copy properties.
      */
    assign<T, U>(target: T, source: U): T & enumsof U;
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    Awaiting More FeedbackThis means we'd like to hear from more people who would be helped by this featureSuggestionAn idea for TypeScript

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions