Skip to content

Commit 68b84f0

Browse files
🤖 Pick PR #60683 (Cache started nonexistent property ...) into release-5.7 (#60686)
Co-authored-by: Wesley Wigham <[email protected]>
1 parent 97fa216 commit 68b84f0

7 files changed

+111
-0
lines changed

‎src/compiler/checker.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34315,6 +34315,13 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
3431534315
}
3431634316

3431734317
function reportNonexistentProperty(propNode: Identifier | PrivateIdentifier, containingType: Type, isUncheckedJS: boolean) {
34318+
const links = getNodeLinks(propNode);
34319+
const cache = (links.nonExistentPropCheckCache ||= new Set());
34320+
const key = `${getTypeId(containingType)}|${isUncheckedJS}`;
34321+
if (cache.has(key)) {
34322+
return;
34323+
}
34324+
cache.add(key);
3431834325
let errorInfo: DiagnosticMessageChain | undefined;
3431934326
let relatedInfo: Diagnostic | undefined;
3432034327
if (!isPrivateIdentifier(propNode) && containingType.flags & TypeFlags.Union && !(containingType.flags & TypeFlags.Primitive)) {

‎src/compiler/types.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6243,6 +6243,7 @@ export interface NodeLinks {
62436243
potentialUnusedRenamedBindingElementsInTypes?: BindingElement[];
62446244
externalHelpersModule?: Symbol; // Resolved symbol for the external helpers module
62456245
instantiationExpressionTypes?: Map<number, Type>; // Cache of instantiation expression types for the node
6246+
nonExistentPropCheckCache?: Set<string>;
62466247
}
62476248

62486249
/** @internal */
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
checkingObjectWithThisInNamePositionNoCrash.ts(2,5): error TS7023: 'doit' implicitly has return type 'any' because it does not have a return type annotation and is referenced directly or indirectly in one of its return expressions.
2+
checkingObjectWithThisInNamePositionNoCrash.ts(4,19): error TS2339: Property 'a' does not exist on type '{ doit(): { [x: number]: string; }; }'.
3+
4+
5+
==== checkingObjectWithThisInNamePositionNoCrash.ts (2 errors) ====
6+
export const thing = {
7+
doit() {
8+
~~~~
9+
!!! error TS7023: 'doit' implicitly has return type 'any' because it does not have a return type annotation and is referenced directly or indirectly in one of its return expressions.
10+
return {
11+
[this.a]: "", // should refer to the outer object with the doit method, notably not present
12+
~
13+
!!! error TS2339: Property 'a' does not exist on type '{ doit(): { [x: number]: string; }; }'.
14+
}
15+
}
16+
}
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
//// [tests/cases/compiler/checkingObjectWithThisInNamePositionNoCrash.ts] ////
2+
3+
//// [checkingObjectWithThisInNamePositionNoCrash.ts]
4+
export const thing = {
5+
doit() {
6+
return {
7+
[this.a]: "", // should refer to the outer object with the doit method, notably not present
8+
}
9+
}
10+
}
11+
12+
//// [checkingObjectWithThisInNamePositionNoCrash.js]
13+
"use strict";
14+
Object.defineProperty(exports, "__esModule", { value: true });
15+
exports.thing = void 0;
16+
exports.thing = {
17+
doit: function () {
18+
var _a;
19+
return _a = {},
20+
_a[this.a] = "",
21+
_a;
22+
}
23+
};
24+
25+
26+
//// [checkingObjectWithThisInNamePositionNoCrash.d.ts]
27+
export declare const thing: {
28+
doit(): {
29+
[x: number]: string;
30+
};
31+
};
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
//// [tests/cases/compiler/checkingObjectWithThisInNamePositionNoCrash.ts] ////
2+
3+
=== checkingObjectWithThisInNamePositionNoCrash.ts ===
4+
export const thing = {
5+
>thing : Symbol(thing, Decl(checkingObjectWithThisInNamePositionNoCrash.ts, 0, 12))
6+
7+
doit() {
8+
>doit : Symbol(doit, Decl(checkingObjectWithThisInNamePositionNoCrash.ts, 0, 22))
9+
10+
return {
11+
[this.a]: "", // should refer to the outer object with the doit method, notably not present
12+
>[this.a] : Symbol([this.a], Decl(checkingObjectWithThisInNamePositionNoCrash.ts, 2, 16))
13+
>this : Symbol(thing, Decl(checkingObjectWithThisInNamePositionNoCrash.ts, 0, 20))
14+
}
15+
}
16+
}
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
//// [tests/cases/compiler/checkingObjectWithThisInNamePositionNoCrash.ts] ////
2+
3+
=== checkingObjectWithThisInNamePositionNoCrash.ts ===
4+
export const thing = {
5+
>thing : { doit(): { [x: number]: string; }; }
6+
> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
7+
>{ doit() { return { [this.a]: "", // should refer to the outer object with the doit method, notably not present } }} : { doit(): { [x: number]: string; }; }
8+
> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
9+
10+
doit() {
11+
>doit : () => { [x: number]: string; }
12+
> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
13+
14+
return {
15+
>{ [this.a]: "", // should refer to the outer object with the doit method, notably not present } : { [x: number]: string; }
16+
> : ^^^^^^^^^^^^^^^^^^^^^^^^
17+
18+
[this.a]: "", // should refer to the outer object with the doit method, notably not present
19+
>[this.a] : string
20+
> : ^^^^^^
21+
>this.a : any
22+
> : ^^^
23+
>this : { doit(): { [x: number]: string; }; }
24+
> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
25+
>a : any
26+
> : ^^^
27+
>"" : ""
28+
> : ^^
29+
}
30+
}
31+
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
// @strict: true
2+
// @declaration: true
3+
export const thing = {
4+
doit() {
5+
return {
6+
[this.a]: "", // should refer to the outer object with the doit method, notably not present
7+
}
8+
}
9+
}

0 commit comments

Comments
 (0)