DEV Community

Discussion on: Indexing objects in TypeScript

Collapse
 
wdoug profile image
Will Douglas

If you want to be extra fancy and not add the intersection with Record<K, unknown> if the key is known to exist on the object type, you can also use conditional types. For example:

export function hasOwnProperty<O extends object, K extends PropertyKey>(
  obj: O,
  key: K,
): obj is ObjectWithKey<O, K> {
  return Object.prototype.hasOwnProperty.call(obj, key);
}

/**
 * This utility type takes an object type O and a key type K. If K is a known 
 * key on O, it evaluates to the original object O. Otherwise, it evaluates to 
 * the object O with an additional key K that has an `unknown` value.
 */
type ObjectWithKey<O extends object, K extends PropertyKey> = K extends keyof O
  ? O
  : O & Record<K, unknown>;
Collapse
 
wdoug profile image
Will Douglas

Actually, the conditional type doesn't work when either of the arguments is itself a generic type (playground example).