diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 6bb0efc2c8322..4ed9ff23498d6 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -261,6 +261,7 @@ import { getContainingClassExcludingClassDecorators, getContainingClassStaticBlock, getContainingFunction, + getContainingFunctionDeclaration, getContainingFunctionOrClassStaticBlock, getDeclarationModifierFlagsFromSymbol, getDeclarationOfKind, @@ -47891,6 +47892,20 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { return errorType; } + // Big hack: force the full check of a generator function when evaluating anything inside it. + const containingFunction = findAncestor(node, node => { + if (isFunctionLikeDeclaration(node)) { + if (node.asteriskToken) { + return true; + } + return "quit"; + } + return false; + }); + if (containingFunction) { + getReturnTypeOfSignature(getSignatureFromDeclaration(containingFunction as FunctionLikeDeclaration)); + } + const classDecl = tryGetClassImplementingOrExtendingExpressionWithTypeArguments(node); const classType = classDecl && getDeclaredTypeOfClassOrInterface(getSymbolOfDeclaration(classDecl.class)); if (isPartOfTypeNode(node)) { diff --git a/tests/cases/fourslash/issue57429.ts b/tests/cases/fourslash/issue57429.ts new file mode 100644 index 0000000000000..ce8aa7ddf2356 --- /dev/null +++ b/tests/cases/fourslash/issue57429.ts @@ -0,0 +1,26 @@ +/// + +// @strict: true + +//// function Builder(def: I) { +//// return def; +//// } +//// +//// interface IThing { +//// doThing: (args: { value: object }) => string +//// doAnotherThing: () => void +//// } +//// +//// Builder({ +//// doThing(args: { value: object }) { +//// const { v/*1*/alue } = this.[|args|] +//// return `${value}` +//// }, +//// doAnotherThing() { }, +//// }) + +verify.quickInfoAt("1", "const value: any"); +verify.getSemanticDiagnostics([{ + message: "Property 'args' does not exist on type 'IThing'.", + code: 2339, +}]); \ No newline at end of file diff --git a/tests/cases/fourslash/issue57585.ts b/tests/cases/fourslash/issue57585.ts new file mode 100644 index 0000000000000..6ad7088c0a9e3 --- /dev/null +++ b/tests/cases/fourslash/issue57585.ts @@ -0,0 +1,29 @@ +/// + +// @strict: true +// @target: esnext +// @lib: esnext + +//// export interface Result { +//// mapErr(fn: (error: E) => F): Result; +//// [Symbol.iterator](): Generator; +//// } +//// +//// declare const okIfObject: ( +//// value: unknown, +//// ) => Result, "ERR_NOT_AN_OBJECT">; +//// +//// declare const okIfInt: (value: unknown) => Result; +//// +//// export declare function Do2(job: () => Generator): void; +//// +//// declare let value: unknown; +//// +//// Do2(function* () { +//// const object = yield* okIfObject(value).mapErr((error) => 0); +//// const age = yield* okIfInt(object.age).mapErr((error) => 0); +//// return { age }; +//// }); + +verify.encodedSemanticClassificationsLength('2020', 132); +verify.getSemanticDiagnostics([]); \ No newline at end of file