mirror of
https://github.com/microsoft/TypeScript.git
synced 2026-02-15 03:23:08 -06:00
Cache started nonexistent property error checks to prevent reentrancy in the check (#60683)
This commit is contained in:
parent
4105134626
commit
517da72a57
@ -34466,6 +34466,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)) {
|
||||
|
||||
@ -6254,6 +6254,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 */
|
||||
|
||||
@ -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; }; }'.
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -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;
|
||||
};
|
||||
};
|
||||
@ -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))
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -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
|
||||
> : ^^^
|
||||
>"" : ""
|
||||
> : ^^
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -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…
x
Reference in New Issue
Block a user