Skip to content

Commit ec48ce8

Browse files
authored
Fixed expando functions with nullish properties (#54728)
1 parent 97ef321 commit ec48ce8

File tree

5 files changed

+264
-1
lines changed

5 files changed

+264
-1
lines changed

src/compiler/checker.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10750,7 +10750,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
1075010750
}
1075110751
}
1075210752
const widened = getWidenedType(addOptionality(type, /*isProperty*/ false, definedInMethod && !definedInConstructor));
10753-
if (symbol.valueDeclaration && filterType(widened, t => !!(t.flags & ~TypeFlags.Nullable)) === neverType) {
10753+
if (symbol.valueDeclaration && isInJSFile(symbol.valueDeclaration) && filterType(widened, t => !!(t.flags & ~TypeFlags.Nullable)) === neverType) {
1075410754
reportImplicitAny(symbol.valueDeclaration, anyType);
1075510755
return anyType;
1075610756
}
Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
//// [tests/cases/compiler/expandoFunctionNullishProperty.ts] ////
2+
3+
//// [expandoFunctionNullishProperty.ts]
4+
// mentioned in https://github.com/microsoft/TypeScript/issues/54220
5+
6+
interface TestNull {
7+
(): void;
8+
readonly prop: null;
9+
}
10+
11+
export function testNull(): TestNull {
12+
function inner() {}
13+
inner.prop = null;
14+
return inner;
15+
}
16+
17+
interface TestNull2 {
18+
(): void;
19+
prop: string | null;
20+
}
21+
22+
export function testNull2(): TestNull2 {
23+
function inner() {}
24+
inner.prop = null;
25+
return inner;
26+
}
27+
28+
interface TestUndefined {
29+
(): void;
30+
readonly prop: undefined;
31+
}
32+
33+
export function testUndefined(): TestUndefined {
34+
function inner() {}
35+
inner.prop = undefined;
36+
return inner;
37+
}
38+
39+
40+
//// [expandoFunctionNullishProperty.js]
41+
// mentioned in https://github.com/microsoft/TypeScript/issues/54220
42+
export function testNull() {
43+
function inner() { }
44+
inner.prop = null;
45+
return inner;
46+
}
47+
export function testNull2() {
48+
function inner() { }
49+
inner.prop = null;
50+
return inner;
51+
}
52+
export function testUndefined() {
53+
function inner() { }
54+
inner.prop = undefined;
55+
return inner;
56+
}
57+
58+
59+
//// [expandoFunctionNullishProperty.d.ts]
60+
interface TestNull {
61+
(): void;
62+
readonly prop: null;
63+
}
64+
export declare function testNull(): TestNull;
65+
interface TestNull2 {
66+
(): void;
67+
prop: string | null;
68+
}
69+
export declare function testNull2(): TestNull2;
70+
interface TestUndefined {
71+
(): void;
72+
readonly prop: undefined;
73+
}
74+
export declare function testUndefined(): TestUndefined;
75+
export {};
Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
//// [tests/cases/compiler/expandoFunctionNullishProperty.ts] ////
2+
3+
=== expandoFunctionNullishProperty.ts ===
4+
// mentioned in https://github.com/microsoft/TypeScript/issues/54220
5+
6+
interface TestNull {
7+
>TestNull : Symbol(TestNull, Decl(expandoFunctionNullishProperty.ts, 0, 0))
8+
9+
(): void;
10+
readonly prop: null;
11+
>prop : Symbol(TestNull.prop, Decl(expandoFunctionNullishProperty.ts, 3, 11))
12+
}
13+
14+
export function testNull(): TestNull {
15+
>testNull : Symbol(testNull, Decl(expandoFunctionNullishProperty.ts, 5, 1))
16+
>TestNull : Symbol(TestNull, Decl(expandoFunctionNullishProperty.ts, 0, 0))
17+
18+
function inner() {}
19+
>inner : Symbol(inner, Decl(expandoFunctionNullishProperty.ts, 7, 38))
20+
21+
inner.prop = null;
22+
>inner.prop : Symbol(inner.prop, Decl(expandoFunctionNullishProperty.ts, 8, 21))
23+
>inner : Symbol(inner, Decl(expandoFunctionNullishProperty.ts, 7, 38))
24+
>prop : Symbol(inner.prop, Decl(expandoFunctionNullishProperty.ts, 8, 21))
25+
26+
return inner;
27+
>inner : Symbol(inner, Decl(expandoFunctionNullishProperty.ts, 7, 38))
28+
}
29+
30+
interface TestNull2 {
31+
>TestNull2 : Symbol(TestNull2, Decl(expandoFunctionNullishProperty.ts, 11, 1))
32+
33+
(): void;
34+
prop: string | null;
35+
>prop : Symbol(TestNull2.prop, Decl(expandoFunctionNullishProperty.ts, 14, 11))
36+
}
37+
38+
export function testNull2(): TestNull2 {
39+
>testNull2 : Symbol(testNull2, Decl(expandoFunctionNullishProperty.ts, 16, 1))
40+
>TestNull2 : Symbol(TestNull2, Decl(expandoFunctionNullishProperty.ts, 11, 1))
41+
42+
function inner() {}
43+
>inner : Symbol(inner, Decl(expandoFunctionNullishProperty.ts, 18, 40))
44+
45+
inner.prop = null;
46+
>inner.prop : Symbol(inner.prop, Decl(expandoFunctionNullishProperty.ts, 19, 21))
47+
>inner : Symbol(inner, Decl(expandoFunctionNullishProperty.ts, 18, 40))
48+
>prop : Symbol(inner.prop, Decl(expandoFunctionNullishProperty.ts, 19, 21))
49+
50+
return inner;
51+
>inner : Symbol(inner, Decl(expandoFunctionNullishProperty.ts, 18, 40))
52+
}
53+
54+
interface TestUndefined {
55+
>TestUndefined : Symbol(TestUndefined, Decl(expandoFunctionNullishProperty.ts, 22, 1))
56+
57+
(): void;
58+
readonly prop: undefined;
59+
>prop : Symbol(TestUndefined.prop, Decl(expandoFunctionNullishProperty.ts, 25, 11))
60+
}
61+
62+
export function testUndefined(): TestUndefined {
63+
>testUndefined : Symbol(testUndefined, Decl(expandoFunctionNullishProperty.ts, 27, 1))
64+
>TestUndefined : Symbol(TestUndefined, Decl(expandoFunctionNullishProperty.ts, 22, 1))
65+
66+
function inner() {}
67+
>inner : Symbol(inner, Decl(expandoFunctionNullishProperty.ts, 29, 48))
68+
69+
inner.prop = undefined;
70+
>inner.prop : Symbol(inner.prop, Decl(expandoFunctionNullishProperty.ts, 30, 21))
71+
>inner : Symbol(inner, Decl(expandoFunctionNullishProperty.ts, 29, 48))
72+
>prop : Symbol(inner.prop, Decl(expandoFunctionNullishProperty.ts, 30, 21))
73+
>undefined : Symbol(undefined)
74+
75+
return inner;
76+
>inner : Symbol(inner, Decl(expandoFunctionNullishProperty.ts, 29, 48))
77+
}
78+
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
//// [tests/cases/compiler/expandoFunctionNullishProperty.ts] ////
2+
3+
=== expandoFunctionNullishProperty.ts ===
4+
// mentioned in https://github.com/microsoft/TypeScript/issues/54220
5+
6+
interface TestNull {
7+
(): void;
8+
readonly prop: null;
9+
>prop : null
10+
}
11+
12+
export function testNull(): TestNull {
13+
>testNull : () => TestNull
14+
15+
function inner() {}
16+
>inner : { (): void; prop: null; }
17+
18+
inner.prop = null;
19+
>inner.prop = null : null
20+
>inner.prop : null
21+
>inner : { (): void; prop: null; }
22+
>prop : null
23+
24+
return inner;
25+
>inner : { (): void; prop: null; }
26+
}
27+
28+
interface TestNull2 {
29+
(): void;
30+
prop: string | null;
31+
>prop : string | null
32+
}
33+
34+
export function testNull2(): TestNull2 {
35+
>testNull2 : () => TestNull2
36+
37+
function inner() {}
38+
>inner : { (): void; prop: null; }
39+
40+
inner.prop = null;
41+
>inner.prop = null : null
42+
>inner.prop : null
43+
>inner : { (): void; prop: null; }
44+
>prop : null
45+
46+
return inner;
47+
>inner : { (): void; prop: null; }
48+
}
49+
50+
interface TestUndefined {
51+
(): void;
52+
readonly prop: undefined;
53+
>prop : undefined
54+
}
55+
56+
export function testUndefined(): TestUndefined {
57+
>testUndefined : () => TestUndefined
58+
59+
function inner() {}
60+
>inner : { (): void; prop: undefined; }
61+
62+
inner.prop = undefined;
63+
>inner.prop = undefined : undefined
64+
>inner.prop : undefined
65+
>inner : { (): void; prop: undefined; }
66+
>prop : undefined
67+
>undefined : undefined
68+
69+
return inner;
70+
>inner : { (): void; prop: undefined; }
71+
}
72+
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
// @strict: true
2+
// @target: esnext
3+
// @declaration: true
4+
5+
// mentioned in https://github.com/microsoft/TypeScript/issues/54220
6+
7+
interface TestNull {
8+
(): void;
9+
readonly prop: null;
10+
}
11+
12+
export function testNull(): TestNull {
13+
function inner() {}
14+
inner.prop = null;
15+
return inner;
16+
}
17+
18+
interface TestNull2 {
19+
(): void;
20+
prop: string | null;
21+
}
22+
23+
export function testNull2(): TestNull2 {
24+
function inner() {}
25+
inner.prop = null;
26+
return inner;
27+
}
28+
29+
interface TestUndefined {
30+
(): void;
31+
readonly prop: undefined;
32+
}
33+
34+
export function testUndefined(): TestUndefined {
35+
function inner() {}
36+
inner.prop = undefined;
37+
return inner;
38+
}

0 commit comments

Comments
 (0)