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

[Feature request] Smarter Object.entries #38

Closed
petervmeijgaard opened this issue Feb 21, 2023 · 5 comments
Closed

[Feature request] Smarter Object.entries #38

petervmeijgaard opened this issue Feb 21, 2023 · 5 comments

Comments

@petervmeijgaard
Copy link

petervmeijgaard commented Feb 21, 2023

This is an amazing project! Thanks a ton for the already great TypeScript resets! 🎉

If possible, I'd love to have a better Object.entries array method that will treat the keys as a const instead of a primitive string/number. This can be useful in the following scenario:

const myVariable = {
  "bar": 1,
  "baz": "foo",
} as const;

// In this example, `key` is typed as `string`.
const a = Object.entries(myVariable).reduce((accumulator, [key, value]) => ({
  ...accumulator,
  [key]: `Value: ${value}`,
}), {});

In the example above, key is a string, but I'd argue that a "bar" | "baz" inferred type would be a better match in this case. I've managed to find a objectEntries helper method that suits my use case and can be used in the following example:

const myVariable = {
  "bar": 1,
  "baz": "foo",
} as const;

type Input<T extends object> = {
  [Key in keyof T]: T[Key];
};

const objectEntries = <T extends object>(
  input: T,
): [key: keyof T, value: T[keyof T]][] =>
  Object.entries<T[keyof T]>(input as Input<T>) as [
    key: keyof T,
    value: T[keyof T],
  ][];

// In this example, `key` is typed as `"bar" | "baz"`
const b = objectEntries(myVariable).reduce((accumulator, [key, value]) => ({
  ...accumulator,
  [key]: `Value: ${value}`,
}), {});

I'm looking forward to your reply and if this is a suitable addition to the project.


More info:

@mattpocock
Copy link
Owner

Take a look at the readme for the reason why I won't be implementing this!

@petervmeijgaard
Copy link
Author

petervmeijgaard commented Feb 21, 2023

Oh my goodness, my apologies. Classic RTFM 😅

Thanks for the quick reply, and the explanation in the readme makes perfect sense. I'm still hoping that this gets resolved in a future TypeScript release, but I won't hold my breath though

@samson-sham
Copy link

samson-sham commented Mar 28, 2023

I would demand this feature as an opt-in feature, rather than "just no"...

@mattpocock
Copy link
Owner

mattpocock commented Mar 28, 2023

I can't be clearer than putting it under a heading in the readme saying 'things we won't be adding'. This doesn't make TS safer, which is the stated aim of this library.

This is good general advice for GitHub - if you have a request and you see that request under a 'won't implement' flag, you probably won't get anywhere by asking for it again.

@texastoland
Copy link

texastoland commented Jul 19, 2023

I'd like to respectfully (not to stir the pot) challenge the assumption that this is unsafe 💭

To review the potential issue you're avoiding:

const type = { total: "TypeScript" }
const subtype = { ...type, hereBeDragons: "🐲" }

// everybody wishes this worked
Object.keys(type).map((key) => type[key].toUpperCase())
// but this corner case would error at runtime
Object.keys(subtype as typeof type).map((key) => type[key].toUpperCase())

The problem with this rationale is a lot of TypeScript is unsound for example:

class Dog { bark() {} }
const dog = () => ({ bark() {} })
const dogs = [new Dog(), dog()]

for (const dog of dogs)
  if (!dog instanceof Dog)
    throw new Error("TypeScript thinks this won't happen")
    // IRL this is problematic working with prototypes

The point of my previous example is it arguably only happens abusing JavaScript.

Do you know some case where being "safe" with these APIs would prevents errors in real-world code?

Or have you already considered a pragmatic set of "unsafe" imports:

// same same like recommended but different
import "@total-typescript/ts-reset/unsafe"

Repository owner locked as resolved and limited conversation to collaborators Jul 19, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants