-
Notifications
You must be signed in to change notification settings - Fork 12.6k
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
Target of object rest destructuring should allow an implicit index signature if its source does #48014
Comments
I think this is a fairly straightforward PR (relatively speaking) if anyone wants to experiment with it |
I recently ran into a similar problem (I think) with TS not complaining about extra methods after destructuring. I believe if a feature like this was implemented I could simplify this (prisma wrapper class) export const Project extends ProjectProperties {
// remove methods from class instance, only send 'fields' to DB
dbSync = async () => {
type StrictPropertyCheck<T, TExpected, TError> = Exclude<keyof T, keyof TExpected> extends never ? {} : TError;
const { dbSync, ...rest }: Project = this;
const data: StrictPropertyCheck<typeof rest, ProjectProperties, 'Fields only.'> = rest;
await prisma.project.update({ where: { id: this.id }, data });
};
} into maybe something like this dbSync = async () => {
const { dbSync, ...data}: Project = this; // remove methods since they are not stored in the DB
await prisma.project.update({ where: { id: this.id }, data }); // would yell if not all removed
}; |
I found destructing the object again allowed it to be passed a function call.
However you still can't access random properties on rest2 even though Typescript is suddenly allowing it as an object with index signature
|
Suggestion
π Search Terms
destructuring assignment, object rest, implicit index signature,
β Viability Checklist
My suggestion meets these guidelines:
β Suggestion
From a comment on the related #42021:
Implicit index signatures are only allowed for "objectish" types that are either object literal types or inferred from an object literal value. They are not permitted for
interface
s or the instance type ofclass
es, as discussed in #15300.When using rest in object destructuring assignment to copy properties from a source object to a new target variable, the new variable is not considered to be "objectish" even if the source expression is. This is surprising as shown by this Stack Overflow question and various examples in #42021.
The proposal here is that the type of the new variable should inherit "objectishness" from the initializing expression.
π Motivating Example
Consider the following example demonstrating the current behavior:
Playground link
It is surprising that while
y
is a copy ofx
and the types ofx
andy
are seemingly identical, you are allowed to callfoo(x)
but prohibited from callingfoo(y)
. The suggestion here is to make it sofoo(y)
succeeds if and only iffoo(x)
succeeds.π» Use Cases
This helps TypeScript more fully support rest destructuring assignment
const {...y} = x
as an alternative toconst y = Object.assign({}, x)
for copying properties into a new object, which is the current workaround for things like this (modulo define-vs-set semantics and other things that go bump in the night).This also helps support the removal of some properties
const { a, ...y } = x
while maintaining "objectishness", which currently doesn't have a nice and simple workaround.The text was updated successfully, but these errors were encountered: