Skip to content

Commit daf0a73

Browse files
authored
Fix lookup of optional methods in declaration emit (microsoft#32094)
1 parent 5289f2e commit daf0a73

9 files changed

+89
-13
lines changed

src/compiler/checker.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4093,7 +4093,7 @@ namespace ts {
40934093
context.enclosingDeclaration = saveEnclosingDeclaration;
40944094
const optionalToken = propertySymbol.flags & SymbolFlags.Optional ? createToken(SyntaxKind.QuestionToken) : undefined;
40954095
if (propertySymbol.flags & (SymbolFlags.Function | SymbolFlags.Method) && !getPropertiesOfObjectType(propertyType).length && !isReadonlySymbol(propertySymbol)) {
4096-
const signatures = getSignaturesOfType(propertyType, SignatureKind.Call);
4096+
const signatures = getSignaturesOfType(filterType(propertyType, t => !(t.flags & TypeFlags.Undefined)), SignatureKind.Call);
40974097
for (const signature of signatures) {
40984098
const methodDeclaration = <MethodSignature>signatureToSignatureDeclarationHelper(signature, SyntaxKind.MethodSignature, context);
40994099
methodDeclaration.name = propertyName;
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
//// [declarationEmitOptionalMethod.ts]
2+
export const Foo = (opts: {
3+
a?(): void,
4+
b?: () => void,
5+
}): {
6+
c?(): void,
7+
d?: () => void,
8+
} => ({ });
9+
10+
//// [declarationEmitOptionalMethod.js]
11+
"use strict";
12+
exports.__esModule = true;
13+
exports.Foo = function (opts) { return ({}); };
14+
15+
16+
//// [declarationEmitOptionalMethod.d.ts]
17+
export declare const Foo: (opts: {
18+
a?(): void;
19+
b?: (() => void) | undefined;
20+
}) => {
21+
c?(): void;
22+
d?: (() => void) | undefined;
23+
};
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
=== tests/cases/compiler/declarationEmitOptionalMethod.ts ===
2+
export const Foo = (opts: {
3+
>Foo : Symbol(Foo, Decl(declarationEmitOptionalMethod.ts, 0, 12))
4+
>opts : Symbol(opts, Decl(declarationEmitOptionalMethod.ts, 0, 20))
5+
6+
a?(): void,
7+
>a : Symbol(a, Decl(declarationEmitOptionalMethod.ts, 0, 27))
8+
9+
b?: () => void,
10+
>b : Symbol(b, Decl(declarationEmitOptionalMethod.ts, 1, 15))
11+
12+
}): {
13+
c?(): void,
14+
>c : Symbol(c, Decl(declarationEmitOptionalMethod.ts, 3, 5))
15+
16+
d?: () => void,
17+
>d : Symbol(d, Decl(declarationEmitOptionalMethod.ts, 4, 15))
18+
19+
} => ({ });
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
=== tests/cases/compiler/declarationEmitOptionalMethod.ts ===
2+
export const Foo = (opts: {
3+
>Foo : (opts: { a?(): void; b?: (() => void) | undefined; }) => { c?(): void; d?: (() => void) | undefined; }
4+
>(opts: { a?(): void, b?: () => void,}): { c?(): void, d?: () => void,} => ({ }) : (opts: { a?(): void; b?: (() => void) | undefined; }) => { c?(): void; d?: (() => void) | undefined; }
5+
>opts : { a?(): void; b?: (() => void) | undefined; }
6+
7+
a?(): void,
8+
>a : (() => void) | undefined
9+
10+
b?: () => void,
11+
>b : (() => void) | undefined
12+
13+
}): {
14+
c?(): void,
15+
>c : (() => void) | undefined
16+
17+
d?: () => void,
18+
>d : (() => void) | undefined
19+
20+
} => ({ });
21+
>({ }) : {}
22+
>{ } : {}
23+

tests/baselines/reference/definiteAssignmentAssertionsWithObjectShortHand.js

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,4 +20,6 @@ declare const a: string | undefined;
2020
declare const foo: {
2121
a: string;
2222
};
23-
declare const bar: {};
23+
declare const bar: {
24+
a?(): void;
25+
};

tests/baselines/reference/definiteAssignmentAssertionsWithObjectShortHand.types

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,8 @@ const foo = { a! }
99
>a : string
1010

1111
const bar = {
12-
>bar : {}
13-
>{ a ? () { }} : {}
12+
>bar : { a?(): void; }
13+
>{ a ? () { }} : { a?(): void; }
1414

1515
a ? () { }
1616
>a : (() => void) | undefined

tests/baselines/reference/strictTypeofUnionNarrowing.types

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -52,15 +52,15 @@ function stringify3(anything: unknown | undefined): string { // should simplify
5252
}
5353

5454
function stringify4(anything: { toString?(): string } | undefined): string {
55-
>stringify4 : (anything: {} | undefined) => string
56-
>anything : {} | undefined
55+
>stringify4 : (anything: { toString?(): string; } | undefined) => string
56+
>anything : { toString?(): string; } | undefined
5757
>toString : (() => string) | undefined
5858

5959
return typeof anything === "string" ? anything.toUpperCase() : "";
6060
>typeof anything === "string" ? anything.toUpperCase() : "" : string
6161
>typeof anything === "string" : boolean
6262
>typeof anything : "string" | "number" | "bigint" | "boolean" | "symbol" | "undefined" | "object" | "function"
63-
>anything : {} | undefined
63+
>anything : { toString?(): string; } | undefined
6464
>"string" : "string"
6565
>anything.toUpperCase() : string
6666
>anything.toUpperCase : () => string

tests/baselines/reference/typeFromContextualThisType.types

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
=== tests/cases/conformance/salsa/bug25926.js ===
22
/** @type {{ a(): void; b?(n: number): number; }} */
33
const o1 = {
4-
>o1 : { a(): void; }
4+
>o1 : { a(): void; b?(n: number): number; }
55
>{ a() { this.b = n => n; }} : { a(): void; }
66

77
a() {
@@ -10,7 +10,7 @@ const o1 = {
1010
this.b = n => n;
1111
>this.b = n => n : (n: number) => number
1212
>this.b : ((n: number) => number) | undefined
13-
>this : { a(): void; }
13+
>this : { a(): void; b?(n: number): number; }
1414
>b : ((n: number) => number) | undefined
1515
>n => n : (n: number) => number
1616
>n : number
@@ -20,7 +20,7 @@ const o1 = {
2020

2121
/** @type {{ d(): void; e?(n: number): number; f?(n: number): number; g?: number }} */
2222
const o2 = {
23-
>o2 : { d(): void; g?: number | undefined; }
23+
>o2 : { d(): void; e?(n: number): number; f?(n: number): number; g?: number | undefined; }
2424
>{ d() { this.e = this.f = m => this.g || m; }} : { d(): void; }
2525

2626
d() {
@@ -29,17 +29,17 @@ const o2 = {
2929
this.e = this.f = m => this.g || m;
3030
>this.e = this.f = m => this.g || m : (m: number) => number
3131
>this.e : ((n: number) => number) | undefined
32-
>this : { d(): void; g?: number | undefined; }
32+
>this : { d(): void; e?(n: number): number; f?(n: number): number; g?: number | undefined; }
3333
>e : ((n: number) => number) | undefined
3434
>this.f = m => this.g || m : (m: number) => number
3535
>this.f : ((n: number) => number) | undefined
36-
>this : { d(): void; g?: number | undefined; }
36+
>this : { d(): void; e?(n: number): number; f?(n: number): number; g?: number | undefined; }
3737
>f : ((n: number) => number) | undefined
3838
>m => this.g || m : (m: number) => number
3939
>m : number
4040
>this.g || m : number
4141
>this.g : number | undefined
42-
>this : { d(): void; g?: number | undefined; }
42+
>this : { d(): void; e?(n: number): number; f?(n: number): number; g?: number | undefined; }
4343
>g : number | undefined
4444
>m : number
4545
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
// @declaration: true
2+
// @strictNullChecks: true
3+
export const Foo = (opts: {
4+
a?(): void,
5+
b?: () => void,
6+
}): {
7+
c?(): void,
8+
d?: () => void,
9+
} => ({ });

0 commit comments

Comments
 (0)