Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Proposal] change Object.create in lib.d.ts #26541

Closed
4 tasks done
texastoland opened this issue Aug 19, 2018 · 2 comments
Closed
4 tasks done

[Proposal] change Object.create in lib.d.ts #26541

texastoland opened this issue Aug 19, 2018 · 2 comments
Labels
Declined The issue was declined as something which matches the TypeScript vision Suggestion An idea for TypeScript

Comments

@texastoland
Copy link
Contributor

texastoland commented Aug 19, 2018

Search Terms

object create null

Suggestion

Change Object.create in lib.d.ts.

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

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

Use Cases

#1108

Examples

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())

Checklist

My suggestion meets these guidelines:

  • This wouldn't be a breaking change in existing TypeScript / JavaScript code
  • This wouldn't change the runtime behavior of existing JavaScript code
  • This could be implemented without emitting different JS based on the types of the expressions
  • This isn't a runtime feature (e.g. new expression-level syntax)
@texastoland texastoland changed the title [Proposal] change in Object.create lib.d.ts [Proposal] change Object.create in lib.d.ts Aug 19, 2018
@RyanCavanaugh RyanCavanaugh added Suggestion An idea for TypeScript Declined The issue was declined as something which matches the TypeScript vision labels Aug 20, 2018
@RyanCavanaugh
Copy link
Member

RyanCavanaugh commented Aug 20, 2018

This is a breaking change. The problem here is that you end up creating a poisoned object where you can't use those fields at all -- this code becomes illegal:

const x = Object.create(null);
// Error, can't assign () => string to never
x.toString = () => "";

It also doesn't catch errors in places where you'd presumably want it to:

function fn(obj: { toString(): string }) { obj.toString() };
const x = Object.create(null);
// No error; crashes
fn(x);

@texastoland
Copy link
Contributor Author

👍🏽 makes sense.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Declined The issue was declined as something which matches the TypeScript vision Suggestion An idea for TypeScript
Projects
None yet
Development

No branches or pull requests

2 participants