From 1518cd98f4096d0e35c8af61d31ce87045babb88 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateusz=20Burzy=C5=84ski?= Date: Wed, 24 May 2023 19:19:01 +0200 Subject: [PATCH] Fixed declaration emit for undefined properties inferred from functions in other array elements (#53938) --- src/compiler/checker.ts | 49 ++++++++++--------- ...nferredUndefinedPropFromFunctionInArray.js | 23 +++++++++ ...edUndefinedPropFromFunctionInArray.symbols | 9 ++++ ...rredUndefinedPropFromFunctionInArray.types | 14 ++++++ ...nferredUndefinedPropFromFunctionInArray.ts | 5 ++ 5 files changed, 76 insertions(+), 24 deletions(-) create mode 100644 tests/baselines/reference/declarationEmitInferredUndefinedPropFromFunctionInArray.js create mode 100644 tests/baselines/reference/declarationEmitInferredUndefinedPropFromFunctionInArray.symbols create mode 100644 tests/baselines/reference/declarationEmitInferredUndefinedPropFromFunctionInArray.types create mode 100644 tests/cases/compiler/declarationEmitInferredUndefinedPropFromFunctionInArray.ts diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 547d5fdafd3..6a95bd7b9b4 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -7126,36 +7126,37 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { const methodDeclaration = signatureToSignatureDeclarationHelper(signature, SyntaxKind.MethodSignature, context, { name: propertyName, questionToken: optionalToken }) as MethodSignature; typeElements.push(preserveCommentsOn(methodDeclaration)); } + if (signatures.length || !optionalToken) { + return; + } + } + let propertyTypeNode: TypeNode; + if (shouldUsePlaceholderForProperty(propertySymbol, context)) { + propertyTypeNode = createElidedInformationPlaceholder(context); } else { - let propertyTypeNode: TypeNode; - if (shouldUsePlaceholderForProperty(propertySymbol, context)) { - propertyTypeNode = createElidedInformationPlaceholder(context); + if (propertyIsReverseMapped) { + context.reverseMappedStack ||= []; + context.reverseMappedStack.push(propertySymbol as ReverseMappedSymbol); } - else { - if (propertyIsReverseMapped) { - context.reverseMappedStack ||= []; - context.reverseMappedStack.push(propertySymbol as ReverseMappedSymbol); - } - propertyTypeNode = propertyType ? serializeTypeForDeclaration(context, propertyType, propertySymbol, saveEnclosingDeclaration) : factory.createKeywordTypeNode(SyntaxKind.AnyKeyword); - if (propertyIsReverseMapped) { - context.reverseMappedStack!.pop(); - } + propertyTypeNode = propertyType ? serializeTypeForDeclaration(context, propertyType, propertySymbol, saveEnclosingDeclaration) : factory.createKeywordTypeNode(SyntaxKind.AnyKeyword); + if (propertyIsReverseMapped) { + context.reverseMappedStack!.pop(); } - - const modifiers = isReadonlySymbol(propertySymbol) ? [factory.createToken(SyntaxKind.ReadonlyKeyword)] : undefined; - if (modifiers) { - context.approximateLength += 9; - } - const propertySignature = factory.createPropertySignature( - modifiers, - propertyName, - optionalToken, - propertyTypeNode); - - typeElements.push(preserveCommentsOn(propertySignature)); } + const modifiers = isReadonlySymbol(propertySymbol) ? [factory.createToken(SyntaxKind.ReadonlyKeyword)] : undefined; + if (modifiers) { + context.approximateLength += 9; + } + const propertySignature = factory.createPropertySignature( + modifiers, + propertyName, + optionalToken, + propertyTypeNode); + + typeElements.push(preserveCommentsOn(propertySignature)); + function preserveCommentsOn(node: T) { if (some(propertySymbol.declarations, d => d.kind === SyntaxKind.JSDocPropertyTag)) { const d = propertySymbol.declarations?.find(d => d.kind === SyntaxKind.JSDocPropertyTag)! as JSDocPropertyTag; diff --git a/tests/baselines/reference/declarationEmitInferredUndefinedPropFromFunctionInArray.js b/tests/baselines/reference/declarationEmitInferredUndefinedPropFromFunctionInArray.js new file mode 100644 index 00000000000..6d59e542802 --- /dev/null +++ b/tests/baselines/reference/declarationEmitInferredUndefinedPropFromFunctionInArray.js @@ -0,0 +1,23 @@ +//// [declarationEmitInferredUndefinedPropFromFunctionInArray.ts] +// repro from https://github.com/microsoft/TypeScript/issues/53914 + +export let b = [{ foo: 0, m() {} }, { bar: 1 }]; + +//// [declarationEmitInferredUndefinedPropFromFunctionInArray.js] +"use strict"; +// repro from https://github.com/microsoft/TypeScript/issues/53914 +Object.defineProperty(exports, "__esModule", { value: true }); +exports.b = void 0; +exports.b = [{ foo: 0, m: function () { } }, { bar: 1 }]; + + +//// [declarationEmitInferredUndefinedPropFromFunctionInArray.d.ts] +export declare let b: ({ + foo: number; + m(): void; + bar?: undefined; +} | { + bar: number; + foo?: undefined; + m?: undefined; +})[]; diff --git a/tests/baselines/reference/declarationEmitInferredUndefinedPropFromFunctionInArray.symbols b/tests/baselines/reference/declarationEmitInferredUndefinedPropFromFunctionInArray.symbols new file mode 100644 index 00000000000..f1de964bf66 --- /dev/null +++ b/tests/baselines/reference/declarationEmitInferredUndefinedPropFromFunctionInArray.symbols @@ -0,0 +1,9 @@ +=== tests/cases/compiler/declarationEmitInferredUndefinedPropFromFunctionInArray.ts === +// repro from https://github.com/microsoft/TypeScript/issues/53914 + +export let b = [{ foo: 0, m() {} }, { bar: 1 }]; +>b : Symbol(b, Decl(declarationEmitInferredUndefinedPropFromFunctionInArray.ts, 2, 10)) +>foo : Symbol(foo, Decl(declarationEmitInferredUndefinedPropFromFunctionInArray.ts, 2, 17)) +>m : Symbol(m, Decl(declarationEmitInferredUndefinedPropFromFunctionInArray.ts, 2, 25)) +>bar : Symbol(bar, Decl(declarationEmitInferredUndefinedPropFromFunctionInArray.ts, 2, 37)) + diff --git a/tests/baselines/reference/declarationEmitInferredUndefinedPropFromFunctionInArray.types b/tests/baselines/reference/declarationEmitInferredUndefinedPropFromFunctionInArray.types new file mode 100644 index 00000000000..ae474c22317 --- /dev/null +++ b/tests/baselines/reference/declarationEmitInferredUndefinedPropFromFunctionInArray.types @@ -0,0 +1,14 @@ +=== tests/cases/compiler/declarationEmitInferredUndefinedPropFromFunctionInArray.ts === +// repro from https://github.com/microsoft/TypeScript/issues/53914 + +export let b = [{ foo: 0, m() {} }, { bar: 1 }]; +>b : ({ foo: number; m(): void; bar?: undefined; } | { bar: number; foo?: undefined; m?: undefined; })[] +>[{ foo: 0, m() {} }, { bar: 1 }] : ({ foo: number; m(): void; } | { bar: number; })[] +>{ foo: 0, m() {} } : { foo: number; m(): void; } +>foo : number +>0 : 0 +>m : () => void +>{ bar: 1 } : { bar: number; } +>bar : number +>1 : 1 + diff --git a/tests/cases/compiler/declarationEmitInferredUndefinedPropFromFunctionInArray.ts b/tests/cases/compiler/declarationEmitInferredUndefinedPropFromFunctionInArray.ts new file mode 100644 index 00000000000..d12a2717ca1 --- /dev/null +++ b/tests/cases/compiler/declarationEmitInferredUndefinedPropFromFunctionInArray.ts @@ -0,0 +1,5 @@ +// @declaration: true + +// repro from https://github.com/microsoft/TypeScript/issues/53914 + +export let b = [{ foo: 0, m() {} }, { bar: 1 }]; \ No newline at end of file