Skip to content

Commit ed570b8

Browse files
committed
Fixed accidental propagation of caching-related objectFlags
1 parent 26eced3 commit ed570b8

File tree

4 files changed

+109
-1
lines changed

4 files changed

+109
-1
lines changed

src/compiler/checker.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16285,7 +16285,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
1628516285
let type = unionTypes.get(id);
1628616286
if (!type) {
1628716287
type = createType(TypeFlags.Union) as UnionType;
16288-
type.objectFlags = objectFlags | getPropagatingFlagsOfTypes(types, /*excludeKinds*/ TypeFlags.Nullable);
16288+
type.objectFlags = (objectFlags | getPropagatingFlagsOfTypes(types, /*excludeKinds*/ TypeFlags.Nullable)) & ~(ObjectFlags.IsUnknownLikeUnionComputed | ObjectFlags.IsUnknownLikeUnion);
1628916289
type.types = types;
1629016290
type.origin = origin;
1629116291
type.aliasSymbol = aliasSymbol;
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
=== tests/cases/compiler/unknownLikeUnionObjectFlagsNotPropagated.ts ===
2+
// repro from #52475#issuecomment-1411215277
3+
4+
type MyType = {} | null | undefined;
5+
>MyType : Symbol(MyType, Decl(unknownLikeUnionObjectFlagsNotPropagated.ts, 0, 0))
6+
7+
const myVar: MyType = null as MyType;
8+
>myVar : Symbol(myVar, Decl(unknownLikeUnionObjectFlagsNotPropagated.ts, 4, 5))
9+
>MyType : Symbol(MyType, Decl(unknownLikeUnionObjectFlagsNotPropagated.ts, 0, 0))
10+
>MyType : Symbol(MyType, Decl(unknownLikeUnionObjectFlagsNotPropagated.ts, 0, 0))
11+
12+
myVar?.toLocaleString;
13+
>myVar?.toLocaleString : Symbol(Object.toLocaleString, Decl(lib.es5.d.ts, --, --))
14+
>myVar : Symbol(myVar, Decl(unknownLikeUnionObjectFlagsNotPropagated.ts, 4, 5))
15+
>toLocaleString : Symbol(Object.toLocaleString, Decl(lib.es5.d.ts, --, --))
16+
17+
myVar;
18+
>myVar : Symbol(myVar, Decl(unknownLikeUnionObjectFlagsNotPropagated.ts, 4, 5))
19+
20+
async function myUnusedFunction() {
21+
>myUnusedFunction : Symbol(myUnusedFunction, Decl(unknownLikeUnionObjectFlagsNotPropagated.ts, 7, 6))
22+
23+
const fetch1 = Promise.resolve(['hello', 'world']);
24+
>fetch1 : Symbol(fetch1, Decl(unknownLikeUnionObjectFlagsNotPropagated.ts, 10, 9))
25+
>Promise.resolve : Symbol(PromiseConstructor.resolve, Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --))
26+
>Promise : Symbol(Promise, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2018.promise.d.ts, --, --))
27+
>resolve : Symbol(PromiseConstructor.resolve, Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --))
28+
29+
const [data1] = await Promise.all([fetch1]);
30+
>data1 : Symbol(data1, Decl(unknownLikeUnionObjectFlagsNotPropagated.ts, 11, 11))
31+
>Promise.all : Symbol(PromiseConstructor.all, Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --))
32+
>Promise : Symbol(Promise, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2018.promise.d.ts, --, --))
33+
>all : Symbol(PromiseConstructor.all, Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --))
34+
>fetch1 : Symbol(fetch1, Decl(unknownLikeUnionObjectFlagsNotPropagated.ts, 10, 9))
35+
36+
data1.length;
37+
>data1.length : Symbol(Array.length, Decl(lib.es5.d.ts, --, --))
38+
>data1 : Symbol(data1, Decl(unknownLikeUnionObjectFlagsNotPropagated.ts, 11, 11))
39+
>length : Symbol(Array.length, Decl(lib.es5.d.ts, --, --))
40+
}
41+
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
=== tests/cases/compiler/unknownLikeUnionObjectFlagsNotPropagated.ts ===
2+
// repro from #52475#issuecomment-1411215277
3+
4+
type MyType = {} | null | undefined;
5+
>MyType : {} | null | undefined
6+
>null : null
7+
8+
const myVar: MyType = null as MyType;
9+
>myVar : MyType
10+
>null as MyType : MyType
11+
>null : null
12+
13+
myVar?.toLocaleString;
14+
>myVar?.toLocaleString : (() => string) | undefined
15+
>myVar : MyType
16+
>toLocaleString : (() => string) | undefined
17+
18+
myVar;
19+
>myVar : MyType
20+
21+
async function myUnusedFunction() {
22+
>myUnusedFunction : () => Promise<void>
23+
24+
const fetch1 = Promise.resolve(['hello', 'world']);
25+
>fetch1 : Promise<string[]>
26+
>Promise.resolve(['hello', 'world']) : Promise<string[]>
27+
>Promise.resolve : { (): Promise<void>; <T>(value: T): Promise<Awaited<T>>; <T>(value: T | PromiseLike<T>): Promise<Awaited<T>>; }
28+
>Promise : PromiseConstructor
29+
>resolve : { (): Promise<void>; <T>(value: T): Promise<Awaited<T>>; <T>(value: T | PromiseLike<T>): Promise<Awaited<T>>; }
30+
>['hello', 'world'] : string[]
31+
>'hello' : "hello"
32+
>'world' : "world"
33+
34+
const [data1] = await Promise.all([fetch1]);
35+
>data1 : string[]
36+
>await Promise.all([fetch1]) : [string[]]
37+
>Promise.all([fetch1]) : Promise<[string[]]>
38+
>Promise.all : { <T>(values: Iterable<T | PromiseLike<T>>): Promise<Awaited<T>[]>; <T extends readonly unknown[] | []>(values: T): Promise<{ -readonly [P in keyof T]: Awaited<T[P]>; }>; }
39+
>Promise : PromiseConstructor
40+
>all : { <T>(values: Iterable<T | PromiseLike<T>>): Promise<Awaited<T>[]>; <T extends readonly unknown[] | []>(values: T): Promise<{ -readonly [P in keyof T]: Awaited<T[P]>; }>; }
41+
>[fetch1] : [Promise<string[]>]
42+
>fetch1 : Promise<string[]>
43+
44+
data1.length;
45+
>data1.length : number
46+
>data1 : string[]
47+
>length : number
48+
}
49+
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
// @strict: true
2+
// @noEmit: true
3+
// @lib: esnext
4+
5+
// repro from #52475#issuecomment-1411215277
6+
7+
type MyType = {} | null | undefined;
8+
9+
const myVar: MyType = null as MyType;
10+
11+
myVar?.toLocaleString;
12+
myVar;
13+
14+
async function myUnusedFunction() {
15+
const fetch1 = Promise.resolve(['hello', 'world']);
16+
const [data1] = await Promise.all([fetch1]);
17+
data1.length;
18+
}

0 commit comments

Comments
 (0)