Description
🔍 Search Terms
The idea came from this Twitter discussion:
https://x.com/Cal_Irvine/status/1920844023507325084
about this code:
const obj = { foo: 10, bar: 20 } as const;
const keys = Object.keys(obj);
and why keys
is of type string[]
I understand that obj can be extended, like in this example:
type MyArgumentObj = {foo: () => void, bar: () => void}
function callThing(input: MyArgumentObj ) {
(Object.keys(input) as (keyof typeof input)[]).forEach((key) => input[key]())
}
const myObj = {
foo: () => undefined,
bar: () => undefined,
extraProp: 'Some metadata'
} as const
callThing(myObj);
This is more of a question that only designers of the language can answer. So this is not something for StackOverflow and I don't see any other place with discussions.
Why not adding a keyword that make the type input: MyArgumentObj
only accept object with the same shape and make sure that it's properly type checked in the whole codebase and not extended
Something like:
type MyArgumentObj = { foo: 10, bar: 20 } is const;
function callThing(input: MyArgumentObj ) {
}
const myObj = {
foo: () => undefined,
bar: () => undefined,
extraProp: 'Some metadata'
};
callThing(myObj);
That will be a type error. If this was implemented, Object.keys()
could return ('foo' | 'bar')[]
as a lot people would expect and complain about. And this const
type could be added to this object as well:
const obj = { foo: 10, bar: 20 } as const;
const keys = Object.keys(obj); // keys will be ('foo' | 'bar')[]
And every code that mutate the object with this type should throw type error.
I'm not sure if this is doable or what are the limitations, so this is more of a question why it's not possible?
Of course the syntax can be different.
✅ Viability Checklist
- This wouldn't be a breaking change in existing TypeScript/JavaScript codeThis wouldn't change the runtime behavior of existing JavaScript codeThis could be implemented without emitting different JS based on the types of the expressionsThis isn't a runtime feature (e.g. library functionality, non-ECMAScript syntax with JavaScript output, new syntax sugar for JS, etc.)This isn't a request to add a new utility type: https://github.com/microsoft/TypeScript/wiki/No-New-Utility-TypesThis feature would agree with the rest of our Design Goals: https://github.com/Microsoft/TypeScript/wiki/TypeScript-Design-Goals
⭐ Suggestion
See above
📃 Motivating Example
See above
💻 Use Cases
See above
Activity
MartinJohns commentedon May 9, 2025
Object.keys(obj)
is intentionally returningstring[]
, because objects are not sealed. They can contain more properties thankeyof T
. There are numerous issue about this, just search for "object.keys".RyanCavanaugh commentedon May 9, 2025
Duplicate #12936
snarbles2 commentedon May 9, 2025
Sounds similar to Exact Types. The problem is if you don't have comprehensive exact types support, there is no shortage of ways of accidentally extending your non-extensible object.
jcubic commentedon May 9, 2025
@RyanCavanaugh Yes it seems this is what I request here. Pretty shame that this feature request is hanging since 2016.