better-typescript-lib icon indicating copy to clipboard operation
better-typescript-lib copied to clipboard

`Object#hasOwnProperty` and `Object.hasOwn` are overly restrictive

Open ehoogeveen-medweb opened this issue 3 years ago • 0 comments
trafficstars

In #4 it was suggested to improve the typing to this is this & Record<Key, unknown> but https://github.com/uhyo/better-typescript-lib/commit/b86460065acbd1a511631e668205b41b1e47946c seems to have set it to something closer to this is {} instead. As a result, none of the properties can queried or assigned to. For example:

const protoObj = { protoProp: 'protoProp' };

const obj: Record<string, string> = Object.create(protoObj);
obj.ownProp = 'ownProp';

for (const key in obj) {
  if (!obj.hasOwnProperty(key)) continue;
  console.log(obj[key]);
}

gives error Element implicitly has an 'any' type because expression of type 'string' can't be used to index type '{}'. No index signature with a parameter of type 'string' was found on type '{}'. (with noImplicitAny enabled). The example is a bit contrived, but this kind of loop is very common in older code where prototypes can't be trusted.

Was the intent to implement something like the intersection suggested in #4? I modified Object.hasOwn locally as follows:

  hasOwn<Obj extends object, Key extends PropertyKey>(
    o: Obj,
    v: Key
  ): o is Obj & (string extends Key
    ? {}
    : number extends Key
    ? {}
    : symbol extends Key
    ? {}
    : Key extends PropertyKey
    ? { [k in Key]: unknown }
    : {})

ehoogeveen-medweb avatar Jun 22 '22 13:06 ehoogeveen-medweb