Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to check if an object type's prototype is Object.prototype in Typescript?

Given an arbitrary type, I want to check if the type is an object whose prototype is Object.prototype. In other words, I want to exclude Functions, Sets, Maps, custom classes, etc. I can't just list every possible object type, since there's an infinite number of custom classes. Is this possible?

I want to do this to recursively apply a mapping to an object. Here's what I have:

type MapDeep<T> = F<
  T extends Primitive ? T
  : T extends Array<infer U> ? Array<MapDeep<U>>
  : T extends ReadonlyArray<infer U> ? ReadonlyArray<MapDeep<U>>
  : T extends Set<infer U> ? Set<MapDeep<U>>
  : T extends Map<infer K, infer V> ? Map<K, MapDeep<V>>
  : T extends Partial<Record<string, any>> ? { [K in keyof T]: MapDeep<T[K]> }
  : T
>;

However, for objects that have prototypes other than Object.prototype, this doesn't work. E.g. MapDeep<() => void> returns F<{}> instead of F<() => void>, since it matches Partial<Record<string, any>>. How can I tell if a type's prototype is Object.prototype?

like image 233
Leo Jiang Avatar asked Aug 22 '21 06:08

Leo Jiang


1 Answers

This is not possible. A typescript type does not contain information about the prototype chain of an object, it only specifies the type interface of properties and their signatures.

like image 135
Bergi Avatar answered Sep 24 '22 21:09

Bergi