Skip to content

Result of Object.create(null) may be passed to template literal #32135

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

Open
erykpiast opened this issue Jun 27, 2019 · 3 comments
Open

Result of Object.create(null) may be passed to template literal #32135

erykpiast opened this issue Jun 27, 2019 · 3 comments
Labels
Awaiting More Feedback This means we'd like to hear from more people who would be helped by this feature Suggestion An idea for TypeScript

Comments

@erykpiast
Copy link

erykpiast commented Jun 27, 2019

TypeScript Version: 3.5.1

Search Terms: template string, template literal, Object.create(null)

Code

`${Object.create(null)}`

Expected behavior: TypeError, as the object passed to the template string has no toString method in the prototype chain (as it has no prototype chain at all).

Actual behavior: Everything goes well in the compiler, but JavaScript reports runtime error (ex. TypeError: Cannot convert object to primitive value in Chrome).

Playground Link: https://www.typescriptlang.org/play/index.html#code/AYEg3g8gRgVgpgYwC4DoECc4EMlwBQB2ArgDYkCUAvsEA

Related Issues:
#30239
#1108

@erykpiast erykpiast changed the title Object without toString method may be passed to template literal Result of Object.create(null) may be passed to template literal Jun 27, 2019
@erykpiast
Copy link
Author

erykpiast commented Jun 27, 2019

It should be possible, however, to pass that weird object-not-object thingy to tagged template literal, as tag function may be able to deal with that.

interface OptionalToString {
    toString?: () => string
}

function tag(_: TemplateStringsArray, value: OptionalToString) {
  if (typeof value.toString !== 'function') {
    return Object.prototype.toString.call(value);
  }

  return value.toString();
}

tag`${Object.create(null)}`;

See this in playground

@AnyhowStep
Copy link
Contributor

Object.create(null) has bitten me in the past. I hate it. I don't like it when developers and libraries use it.

It's because of them, I need to do stuff like Object.prototype.hasOwnProperty.call(obj, k)

Because obj.hasOwnProperty fails for Object.create(null)

You just have to use libraries that actually support it and remember to support it, yourself.

It's not a TS problem

@RyanCavanaugh RyanCavanaugh added Awaiting More Feedback This means we'd like to hear from more people who would be helped by this feature Suggestion An idea for TypeScript labels Jun 27, 2019
@fatcerberus
Copy link

Because obj.hasOwnProperty fails for Object.create(null)

Actually this is usually why you would use it: because you’re using an object as a dictionary and don’t want anything from Object.prototype interfering. Admittedly it’s less useful now that we have Map but it did serve a useful purpose when it was introduced.

If you ever wondered why we have a bunch of a static methods on Object now, e.g., Object.keys, rather than them being direct instance methods—this is why.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Awaiting More Feedback This means we'd like to hear from more people who would be helped by this feature Suggestion An idea for TypeScript
Projects
None yet
Development

No branches or pull requests

4 participants