question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

No way to type an object with null prototype

See original GitHub issue

Currently the base type of all objects in TS seems to be {}, which looks like an empty type but actually has members inherited from the Object object. This leaves no way to express a type with null prototype.

var foo: ??? = Object.create(null);
foo.toString(); // Want a compile error here

I did accidentally discover that it’s possible to type a variable as void:

var foo: void = Object.create(null);

This appears to suppress intellisense for members in VS and the playground, and it is assignable to any (Object.keys(foo) compiles), so it would seem to be what I’m looking for. However this still lets foo.toString() compile somehow - I imagine the void type is getting elevated to Object automatically.

Edit: Ryan’s workaround to subtype Object and override all its members to void prevents those properties from being called as functions, but as he points out, that doesn’t prevent them from being accessed.

var bar = foo.toString; // Want a compiler error here too. Won't get one with Ryan's workaround.

Issue Analytics

  • State:open
  • Created 9 years ago
  • Reactions:23
  • Comments:19 (14 by maintainers)

github_iconTop GitHub Comments

7reactions
KilianKilmistercommented, Sep 8, 2020

If i’m looking to create a large inheritance structure, I prefer them to start on a null-prototype, It inherently protects them from possible prototype polution on the Object.prototype and as I basically never need to support the legacy Object.prototype methods, there is no real downside.

The lack of a proper Null object type in TS has made me use it less, and i dislike that.

6reactions
texastolandcommented, Aug 18, 2018

We are not really looking for a formal proposal, just a formulation for what changes would be needed to implement, and what impact this has on other parts of the type system.

@mhegazy @RyanCavanaugh what would you think about just changing lib.d.ts like below?

namespace Object {
  export type NullPrototype = Record<keyof Object, never>
}

interface ObjectConstructor {
  create
    <T extends object | null>
    (proto: T):
    T extends null ? Object.NullPrototype : T
}

Playground

interface IDictLike<T> {[key: string]: T}
type DictLike = IDictLike<string> & Object.NullPrototype
const dictLike: DictLike = Object.create(null)

console.log(dictLike.key)
console.log(dictLike.toString())
//          ^^^^^^^^^^^^^^^^^^^
// Cannot invoke an expression whose type lacks a call signature.
// Type 'never' has no compatible call signatures.

// Same type as Object.create(Array.prototype)
const arrayLike = Object.create([])
console.log(arrayLike.key)
//                    ^^^
// Property 'key' does not exist on type 'any[]'. Did you mean 'keys'?
console.log(arrayLike.toString())
Read more comments on GitHub >

github_iconTop Results From Across the Web

how to fix [Object: null prototype] { title: 'product' }
There is a way to create "empty objects", meaning objects without any properties / prototype, and that is Object.create(null) .
Read more >
JavaScript and object with null prototype - LinkedIn
Object with null prototype and its purpose​​ If you create an object in JavaScript - it has some methods by default, such as...
Read more >
Creating Objects With A Null Prototype In Node.js
Ben Nadel looks at how to use Object.create() in Node.js to create an object that has no prototype. Such an object can reduce...
Read more >
Object.prototype.constructor - JavaScript - MDN Web Docs
Any object (with the exception of null prototype objects) will have a ... that points to the constructor type for that object —...
Read more >
How to Check for an Object in Javascript (Object Null Check)
That code checks that the variable object does not have the value null . ... The “best method” of type checking in Javascript...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found