Skip to content
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

🤖 Pick PR #60683 (Cache started nonexistent property ...) into release-5.7 #60686

Merged
merged 1 commit into from
Dec 5, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions src/compiler/checker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34315,6 +34315,13 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
}

function reportNonexistentProperty(propNode: Identifier | PrivateIdentifier, containingType: Type, isUncheckedJS: boolean) {
const links = getNodeLinks(propNode);
const cache = (links.nonExistentPropCheckCache ||= new Set());
const key = `${getTypeId(containingType)}|${isUncheckedJS}`;
if (cache.has(key)) {
return;
}
cache.add(key);
let errorInfo: DiagnosticMessageChain | undefined;
let relatedInfo: Diagnostic | undefined;
if (!isPrivateIdentifier(propNode) && containingType.flags & TypeFlags.Union && !(containingType.flags & TypeFlags.Primitive)) {
Expand Down
1 change: 1 addition & 0 deletions src/compiler/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6243,6 +6243,7 @@ export interface NodeLinks {
potentialUnusedRenamedBindingElementsInTypes?: BindingElement[];
externalHelpersModule?: Symbol; // Resolved symbol for the external helpers module
instantiationExpressionTypes?: Map<number, Type>; // Cache of instantiation expression types for the node
nonExistentPropCheckCache?: Set<string>;
}

/** @internal */
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
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.
checkingObjectWithThisInNamePositionNoCrash.ts(4,19): error TS2339: Property 'a' does not exist on type '{ doit(): { [x: number]: string; }; }'.


==== checkingObjectWithThisInNamePositionNoCrash.ts (2 errors) ====
export const thing = {
doit() {
~~~~
!!! 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.
return {
[this.a]: "", // should refer to the outer object with the doit method, notably not present
~
!!! error TS2339: Property 'a' does not exist on type '{ doit(): { [x: number]: string; }; }'.
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
//// [tests/cases/compiler/checkingObjectWithThisInNamePositionNoCrash.ts] ////

//// [checkingObjectWithThisInNamePositionNoCrash.ts]
export const thing = {
doit() {
return {
[this.a]: "", // should refer to the outer object with the doit method, notably not present
}
}
}

//// [checkingObjectWithThisInNamePositionNoCrash.js]
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.thing = void 0;
exports.thing = {
doit: function () {
var _a;
return _a = {},
_a[this.a] = "",
_a;
}
};


//// [checkingObjectWithThisInNamePositionNoCrash.d.ts]
export declare const thing: {
doit(): {
[x: number]: string;
};
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
//// [tests/cases/compiler/checkingObjectWithThisInNamePositionNoCrash.ts] ////

=== checkingObjectWithThisInNamePositionNoCrash.ts ===
export const thing = {
>thing : Symbol(thing, Decl(checkingObjectWithThisInNamePositionNoCrash.ts, 0, 12))

doit() {
>doit : Symbol(doit, Decl(checkingObjectWithThisInNamePositionNoCrash.ts, 0, 22))

return {
[this.a]: "", // should refer to the outer object with the doit method, notably not present
>[this.a] : Symbol([this.a], Decl(checkingObjectWithThisInNamePositionNoCrash.ts, 2, 16))
>this : Symbol(thing, Decl(checkingObjectWithThisInNamePositionNoCrash.ts, 0, 20))
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
//// [tests/cases/compiler/checkingObjectWithThisInNamePositionNoCrash.ts] ////

=== checkingObjectWithThisInNamePositionNoCrash.ts ===
export const thing = {
>thing : { doit(): { [x: number]: string; }; }
> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
>{ doit() { return { [this.a]: "", // should refer to the outer object with the doit method, notably not present } }} : { doit(): { [x: number]: string; }; }
> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

doit() {
>doit : () => { [x: number]: string; }
> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

return {
>{ [this.a]: "", // should refer to the outer object with the doit method, notably not present } : { [x: number]: string; }
> : ^^^^^^^^^^^^^^^^^^^^^^^^

[this.a]: "", // should refer to the outer object with the doit method, notably not present
>[this.a] : string
> : ^^^^^^
>this.a : any
> : ^^^
>this : { doit(): { [x: number]: string; }; }
> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
>a : any
> : ^^^
>"" : ""
> : ^^
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
// @strict: true
// @declaration: true
export const thing = {
doit() {
return {
[this.a]: "", // should refer to the outer object with the doit method, notably not present
}
}
}
Loading