-
Notifications
You must be signed in to change notification settings - Fork 12.7k
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
Fix2 get constraint of indexed access #17912
Conversation
1. `T[K]` now correctly produces `number` when `K extends string, T extends Record<K, number>`. 2. `T[K]` no longer allows any type to be assigned to it when `T extends object, K extends keyof T`. Previously both of these cases failed in getConstraintOfIndexedAccessType because both bases followed `K`'s base constraint to `string` and then incorrectly produced `any` for types (like `object`) with no string index signature. In (1), this produced an error in checkBinaryLikeExpression`. In (2), this failed to produce an error in `checkTypeRelatedTo`.
@ahejlsberg this undoes a change you added in the fix for #17521, but doesn't break any tests. I looked at the commit and the associated tests and the rest of the change looks like it handles types with index signatures, not mapped types. Regardless, you should take a look and then we can talk about the right way to fix this bug (#17069) at the same time as #17521's fix. |
This fixes some new, erroneous errors from our RWC tests, as in this example: // @declaration: true
// @jsx: react
// @module: commonjs
// @target: es5
// @experimentalDecorators: true
// @filename: index.ts
declare function cloneDeep(x: any): any;
abstract class ClonableModel<ActualType, CreatableType> {
constructor(objectToEncapsulate?: CreatableType) {
if (objectToEncapsulate) {
for (var key in objectToEncapsulate) {
if (objectToEncapsulate.hasOwnProperty(key)) {
this[key] = objectToEncapsulate[key];
}
}
}
}
clone(): ActualType {
let newT = new (Object.getPrototypeOf(this).constructor)();
for (var key in this) {
if (this.hasOwnProperty(key)) {
const thisProp = this[key];
if (thisProp instanceof ClonableModel) { // Right now, this line gives an error, but should not
newT[key] = thisProp.clone();
} else {
newT[key] = cloneDeep(thisProp);
}
}
}
return newT;
}
}
export default ClonableModel; |
Can you look at #17166 and decide whether it is related to this issue? |
It's related but this fix doesn't cover it. It the no-constraint exit explicitly only applies to I still need to look at the second bug in #17166, but it appears to be different. |
`K = keyof T` was already correctly disallowed.
Also fix test failure from last commit.
The second bug in #17166 is not a bug. It's by design that |
@ahejlsberg mind taking a look at this? It sounds like people keep running into it. |
After merging with master, even erroneous tests generate types and symbols baselines
Also rename transformIndexedAccessType to simplifyIndexedAccessType
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Approved with the suggested name change.
src/compiler/checker.ts
Outdated
@@ -8350,7 +8356,7 @@ namespace ts { | |||
|
|||
// Transform an indexed access to a simpler form, if possible. Return the simpler form, or return | |||
// undefined if no transformation is possible. | |||
function getTransformedIndexedAccessType(type: IndexedAccessType): Type { | |||
function simplifyIndexedAccessType(type: IndexedAccessType): Type { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
getSimplifiedIndexAccessType
could this pr break #12215 (comment) ? |
Fixes #17069
Fixes #17166
Fixes #15371
Fixes #19298
Fixes some regressions in RWC.
T[K]
now correctly producesnumber
whenK extends string, T extends Record<K, number>
.T[K]
no longer allows any type to be assigned to it whenT extends object, K extends keyof T
.Previously both of these cases failed in
getConstraintOfIndexedAccessType
because both bases followedK
's base constraint tostring
and then incorrectly producedany
for types (likeobject
) with no string index signature. In (1), this produced an error incheckBinaryLikeExpression
. In (2), this failed to produce an error incheckTypeRelatedTo
.The fix has some additional pieces.
In order to fix (1), not only does the index type parameter need to be kept around, the base constraint of
T extends Record<K, number>
needs to beRecord<K, number>
not{}
so thatRecord<K, number>[K]
producesnumber
. So I changedcomputeBaseConstraint
to only chaseT extends Record<K, number>
back toRecord<K, number>
, not all the way to{}
.In order to fix (2), any index type whose base constraint is string, whether it came from
keyof T
or not, is going to (incorrectly) produceany
when indexing a type that doesn't have a string index signature -- the test case specifically triesobject[string]
. So I added an early exit togetConstraintOfIndexedAccessType
that returnsundefined
in this case.(This is a redo of #17870 after it got merged early by mistake.)
No longer fixes #17847, but previous commits contained a fix for it.