-
Notifications
You must be signed in to change notification settings - Fork 12.5k
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
object isn't subscriptable with string key when enumerating keys #56787
Comments
|
In this particular case, I'm writing a function to search arbitrary objects. I want to enumerate all properties and update them using Object.keys/Object.entries, and I want TypeScript to be okay with that. The production code looks more like: if (typeof thing === "object" && thing !== null && !Array.isArray(thing)) {
// at this point, all we know is that it's an object
// enumerate object props
} Ideally, TypeScript would be okay with this indexing, since JS allows it without issue and behaves as expected. |
See #13254 and #12253 (comment) |
This is such a weird argument. I use TypeScript because it doesn't allow all the crap that JavaScript allows. |
If your coding style and guidelines give you more predictability on what properties arbitrary objects have (or maybe what properties specific subsets of objects have), you can add more overloads to |
@MartinJohns @nmain I promise I appreciate strong mapped types as much as anyone else. The issue is that Object.keys and Object.entries always returns string keys, regardless of the type. In this particular case, I'm writing a function that enumerates an arbitrary object graph that comes from another library, which is attached to error metadata, so it's not an issue of "fix your code base to be better" βΒ not my code base :). If it helps, I will offer that I really did not enjoy writing this code. If you find yourself in the position of writing code like this, my issue is that you will have to cast the object to My ask is that in the particular case where the keys come from calling Object.keys or Object.entries on an object, the keys be allowed to subscript that object without casting because, well, they are. While this case is somewhat narrow, writing utility-type code that enumerates keys and values to manipulate the object based on some rule/predicate isn't uncommon. I hope that clarifies the ask. I can understand if/why TS won't take up an improvement here. There is a workaround, which is you do the classic: for (const key in obj) {
if (Object.hasOwn(obj, key)) {
obj[key] = β¦
}
} TS has no issue with this, but I think the ergonomics of Object.keys and Object.values are better. |
Not always. const foobar = { foo: "foo", bar: 777 };
const foo: { foo: string } = foobar;
console.log(Object.keys(foo)); // [ "foo", "bar" ] ...which is why
This would require |
Ah makes sense β thanks! |
π Search Terms
π Version & Regression Information
β― Playground Link
https://www.typescriptlang.org/play?#code/MYewdgzgLgBAhjAvDA3jKAnArgUwFwwCMMAvgNwCwAUNQGZZjBQCW4MWADgCZxQ4CCAG0EAFDCA4QAPABUYOAB58wXCKhIA+ABQgARgCsCMgJSpqMGLRAYYW0JFgBrHAE8YIWjADyBnEwB0zi4QOgbGpijmFu4GANpBALpIMABMlFQWJDDUJNScPHxCouKSWnDG1NT2ECCCOP6CIADmZcZAA
π» Code
π Actual behavior
TS emits: "Element implicitly has an 'any' type because expression of type 'string' can't be used to index type '{}'.
No index signature with a parameter of type 'string' was found on type '{}'."
π Expected behavior
In the context of
Object.keys
andObject.entries
, TS should allow indexing using the returned key. As much as I dislike the below code, it is valid:Additional information about the issue
No response
The text was updated successfully, but these errors were encountered: