Skip to content

Commit d25cfb5

Browse files
committed
Add a test case for contextually typed return types of an async function when the contextual type is a union of a promise and of a different type
1 parent 92f54d6 commit d25cfb5

4 files changed

+206
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
tests/cases/conformance/types/contextualTypes/asyncFunctions/contextuallyTypeAsyncFunctionReturnTypeFromUnion.ts(11,23): error TS2322: Type 'Promise<{ count: number; } | StateMachine<{ count: number; }>>' is not assignable to type 'Promise<{ count: number; }> | StateMachine<{ count: number; }>'.
2+
Type 'Promise<{ count: number; } | StateMachine<{ count: number; }>>' is not assignable to type 'Promise<{ count: number; }>'.
3+
Type '{ count: number; } | StateMachine<{ count: number; }>' is not assignable to type '{ count: number; }'.
4+
Property 'count' is missing in type 'StateMachine<{ count: number; }>' but required in type '{ count: number; }'.
5+
tests/cases/conformance/types/contextualTypes/asyncFunctions/contextuallyTypeAsyncFunctionReturnTypeFromUnion.ts(12,11): error TS2322: Type '() => Promise<{ count: number; } | StateMachine<{ count: number; }>>' is not assignable to type '() => Promise<{ count: number; }> | StateMachine<{ count: number; }>'.
6+
Type 'Promise<{ count: number; } | StateMachine<{ count: number; }>>' is not assignable to type 'Promise<{ count: number; }> | StateMachine<{ count: number; }>'.
7+
Type 'Promise<{ count: number; } | StateMachine<{ count: number; }>>' is not assignable to type 'Promise<{ count: number; }>'.
8+
tests/cases/conformance/types/contextualTypes/asyncFunctions/contextuallyTypeAsyncFunctionReturnTypeFromUnion.ts(19,22): error TS2322: Type 'Promise<{ count: number; } | StateMachine<{ count: number; }>>' is not assignable to type 'Promise<{ count: number; }> | StateMachine<{ count: number; }>'.
9+
Type 'Promise<{ count: number; } | StateMachine<{ count: number; }>>' is not assignable to type 'Promise<{ count: number; }>'.
10+
Type '{ count: number; } | StateMachine<{ count: number; }>' is not assignable to type '{ count: number; }'.
11+
Property 'count' is missing in type 'StateMachine<{ count: number; }>' but required in type '{ count: number; }'.
12+
13+
14+
==== tests/cases/conformance/types/contextualTypes/asyncFunctions/contextuallyTypeAsyncFunctionReturnTypeFromUnion.ts (3 errors) ====
15+
declare class StateMachine<T> {
16+
onDone: (a: T) => void;
17+
}
18+
19+
declare function createMachine<T>(implementations: {
20+
services: Record<string, () => Promise<T> | StateMachine<T>>;
21+
}): void;
22+
23+
createMachine<{ count: number }>({
24+
services: {
25+
test: async () => Promise.reject("some err"),
26+
~~~~~~~~~~~~~~~~~~~~~~~~~~
27+
!!! error TS2322: Type 'Promise<{ count: number; } | StateMachine<{ count: number; }>>' is not assignable to type 'Promise<{ count: number; }> | StateMachine<{ count: number; }>'.
28+
!!! error TS2322: Type 'Promise<{ count: number; } | StateMachine<{ count: number; }>>' is not assignable to type 'Promise<{ count: number; }>'.
29+
!!! error TS2322: Type '{ count: number; } | StateMachine<{ count: number; }>' is not assignable to type '{ count: number; }'.
30+
!!! error TS2322: Property 'count' is missing in type 'StateMachine<{ count: number; }>' but required in type '{ count: number; }'.
31+
!!! related TS2728 tests/cases/conformance/types/contextualTypes/asyncFunctions/contextuallyTypeAsyncFunctionReturnTypeFromUnion.ts:9:17: 'count' is declared here.
32+
!!! related TS6502 tests/cases/conformance/types/contextualTypes/asyncFunctions/contextuallyTypeAsyncFunctionReturnTypeFromUnion.ts:6:28: The expected type comes from the return type of this signature.
33+
async test2() {
34+
~~~~~
35+
!!! error TS2322: Type '() => Promise<{ count: number; } | StateMachine<{ count: number; }>>' is not assignable to type '() => Promise<{ count: number; }> | StateMachine<{ count: number; }>'.
36+
!!! error TS2322: Type 'Promise<{ count: number; } | StateMachine<{ count: number; }>>' is not assignable to type 'Promise<{ count: number; }> | StateMachine<{ count: number; }>'.
37+
!!! error TS2322: Type 'Promise<{ count: number; } | StateMachine<{ count: number; }>>' is not assignable to type 'Promise<{ count: number; }>'.
38+
return Promise.reject("some err");
39+
},
40+
},
41+
});
42+
43+
function fn1(): () => Promise<{ count: number }> | StateMachine<{ count: number }> {
44+
return async () => Promise.reject('some err')
45+
~~~~~~~~~~~~~~~~~~~~~~~~~~
46+
!!! error TS2322: Type 'Promise<{ count: number; } | StateMachine<{ count: number; }>>' is not assignable to type 'Promise<{ count: number; }> | StateMachine<{ count: number; }>'.
47+
!!! error TS2322: Type 'Promise<{ count: number; } | StateMachine<{ count: number; }>>' is not assignable to type 'Promise<{ count: number; }>'.
48+
!!! error TS2322: Type '{ count: number; } | StateMachine<{ count: number; }>' is not assignable to type '{ count: number; }'.
49+
!!! error TS2322: Property 'count' is missing in type 'StateMachine<{ count: number; }>' but required in type '{ count: number; }'.
50+
!!! related TS2728 tests/cases/conformance/types/contextualTypes/asyncFunctions/contextuallyTypeAsyncFunctionReturnTypeFromUnion.ts:18:33: 'count' is declared here.
51+
!!! related TS6502 tests/cases/conformance/types/contextualTypes/asyncFunctions/contextuallyTypeAsyncFunctionReturnTypeFromUnion.ts:18:17: The expected type comes from the return type of this signature.
52+
}
53+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
=== tests/cases/conformance/types/contextualTypes/asyncFunctions/contextuallyTypeAsyncFunctionReturnTypeFromUnion.ts ===
2+
declare class StateMachine<T> {
3+
>StateMachine : Symbol(StateMachine, Decl(contextuallyTypeAsyncFunctionReturnTypeFromUnion.ts, 0, 0))
4+
>T : Symbol(T, Decl(contextuallyTypeAsyncFunctionReturnTypeFromUnion.ts, 0, 27))
5+
6+
onDone: (a: T) => void;
7+
>onDone : Symbol(StateMachine.onDone, Decl(contextuallyTypeAsyncFunctionReturnTypeFromUnion.ts, 0, 31))
8+
>a : Symbol(a, Decl(contextuallyTypeAsyncFunctionReturnTypeFromUnion.ts, 1, 11))
9+
>T : Symbol(T, Decl(contextuallyTypeAsyncFunctionReturnTypeFromUnion.ts, 0, 27))
10+
}
11+
12+
declare function createMachine<T>(implementations: {
13+
>createMachine : Symbol(createMachine, Decl(contextuallyTypeAsyncFunctionReturnTypeFromUnion.ts, 2, 1))
14+
>T : Symbol(T, Decl(contextuallyTypeAsyncFunctionReturnTypeFromUnion.ts, 4, 31))
15+
>implementations : Symbol(implementations, Decl(contextuallyTypeAsyncFunctionReturnTypeFromUnion.ts, 4, 34))
16+
17+
services: Record<string, () => Promise<T> | StateMachine<T>>;
18+
>services : Symbol(services, Decl(contextuallyTypeAsyncFunctionReturnTypeFromUnion.ts, 4, 52))
19+
>Record : Symbol(Record, Decl(lib.es5.d.ts, --, --))
20+
>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, --, --))
21+
>T : Symbol(T, Decl(contextuallyTypeAsyncFunctionReturnTypeFromUnion.ts, 4, 31))
22+
>StateMachine : Symbol(StateMachine, Decl(contextuallyTypeAsyncFunctionReturnTypeFromUnion.ts, 0, 0))
23+
>T : Symbol(T, Decl(contextuallyTypeAsyncFunctionReturnTypeFromUnion.ts, 4, 31))
24+
25+
}): void;
26+
27+
createMachine<{ count: number }>({
28+
>createMachine : Symbol(createMachine, Decl(contextuallyTypeAsyncFunctionReturnTypeFromUnion.ts, 2, 1))
29+
>count : Symbol(count, Decl(contextuallyTypeAsyncFunctionReturnTypeFromUnion.ts, 8, 15))
30+
31+
services: {
32+
>services : Symbol(services, Decl(contextuallyTypeAsyncFunctionReturnTypeFromUnion.ts, 8, 34))
33+
34+
test: async () => Promise.reject("some err"),
35+
>test : Symbol(test, Decl(contextuallyTypeAsyncFunctionReturnTypeFromUnion.ts, 9, 13))
36+
>Promise.reject : Symbol(PromiseConstructor.reject, Decl(lib.es2015.promise.d.ts, --, --))
37+
>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, --, --))
38+
>reject : Symbol(PromiseConstructor.reject, Decl(lib.es2015.promise.d.ts, --, --))
39+
40+
async test2() {
41+
>test2 : Symbol(test2, Decl(contextuallyTypeAsyncFunctionReturnTypeFromUnion.ts, 10, 49))
42+
43+
return Promise.reject("some err");
44+
>Promise.reject : Symbol(PromiseConstructor.reject, Decl(lib.es2015.promise.d.ts, --, --))
45+
>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, --, --))
46+
>reject : Symbol(PromiseConstructor.reject, Decl(lib.es2015.promise.d.ts, --, --))
47+
48+
},
49+
},
50+
});
51+
52+
function fn1(): () => Promise<{ count: number }> | StateMachine<{ count: number }> {
53+
>fn1 : Symbol(fn1, Decl(contextuallyTypeAsyncFunctionReturnTypeFromUnion.ts, 15, 3))
54+
>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, --, --))
55+
>count : Symbol(count, Decl(contextuallyTypeAsyncFunctionReturnTypeFromUnion.ts, 17, 31))
56+
>StateMachine : Symbol(StateMachine, Decl(contextuallyTypeAsyncFunctionReturnTypeFromUnion.ts, 0, 0))
57+
>count : Symbol(count, Decl(contextuallyTypeAsyncFunctionReturnTypeFromUnion.ts, 17, 65))
58+
59+
return async () => Promise.reject('some err')
60+
>Promise.reject : Symbol(PromiseConstructor.reject, Decl(lib.es2015.promise.d.ts, --, --))
61+
>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, --, --))
62+
>reject : Symbol(PromiseConstructor.reject, Decl(lib.es2015.promise.d.ts, --, --))
63+
}
64+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
=== tests/cases/conformance/types/contextualTypes/asyncFunctions/contextuallyTypeAsyncFunctionReturnTypeFromUnion.ts ===
2+
declare class StateMachine<T> {
3+
>StateMachine : StateMachine<T>
4+
5+
onDone: (a: T) => void;
6+
>onDone : (a: T) => void
7+
>a : T
8+
}
9+
10+
declare function createMachine<T>(implementations: {
11+
>createMachine : <T>(implementations: { services: Record<string, () => Promise<T> | StateMachine<T>>;}) => void
12+
>implementations : { services: Record<string, () => Promise<T> | StateMachine<T>>; }
13+
14+
services: Record<string, () => Promise<T> | StateMachine<T>>;
15+
>services : Record<string, () => Promise<T> | StateMachine<T>>
16+
17+
}): void;
18+
19+
createMachine<{ count: number }>({
20+
>createMachine<{ count: number }>({ services: { test: async () => Promise.reject("some err"), async test2() { return Promise.reject("some err"); }, },}) : void
21+
>createMachine : <T>(implementations: { services: Record<string, () => Promise<T> | StateMachine<T>>; }) => void
22+
>count : number
23+
>{ services: { test: async () => Promise.reject("some err"), async test2() { return Promise.reject("some err"); }, },} : { services: { test: () => Promise<{ count: number; } | StateMachine<{ count: number; }>>; test2(): Promise<{ count: number; } | StateMachine<{ count: number; }>>; }; }
24+
25+
services: {
26+
>services : { test: () => Promise<{ count: number; } | StateMachine<{ count: number; }>>; test2(): Promise<{ count: number; } | StateMachine<{ count: number; }>>; }
27+
>{ test: async () => Promise.reject("some err"), async test2() { return Promise.reject("some err"); }, } : { test: () => Promise<{ count: number; } | StateMachine<{ count: number; }>>; test2(): Promise<{ count: number; } | StateMachine<{ count: number; }>>; }
28+
29+
test: async () => Promise.reject("some err"),
30+
>test : () => Promise<{ count: number; } | StateMachine<{ count: number; }>>
31+
>async () => Promise.reject("some err") : () => Promise<{ count: number; } | StateMachine<{ count: number; }>>
32+
>Promise.reject("some err") : Promise<{ count: number; } | StateMachine<{ count: number; }>>
33+
>Promise.reject : <T = never>(reason?: any) => Promise<T>
34+
>Promise : PromiseConstructor
35+
>reject : <T = never>(reason?: any) => Promise<T>
36+
>"some err" : "some err"
37+
38+
async test2() {
39+
>test2 : () => Promise<{ count: number; } | StateMachine<{ count: number; }>>
40+
41+
return Promise.reject("some err");
42+
>Promise.reject("some err") : Promise<{ count: number; } | StateMachine<{ count: number; }>>
43+
>Promise.reject : <T = never>(reason?: any) => Promise<T>
44+
>Promise : PromiseConstructor
45+
>reject : <T = never>(reason?: any) => Promise<T>
46+
>"some err" : "some err"
47+
48+
},
49+
},
50+
});
51+
52+
function fn1(): () => Promise<{ count: number }> | StateMachine<{ count: number }> {
53+
>fn1 : () => () => Promise<{ count: number;}> | StateMachine<{ count: number;}>
54+
>count : number
55+
>count : number
56+
57+
return async () => Promise.reject('some err')
58+
>async () => Promise.reject('some err') : () => Promise<{ count: number; } | StateMachine<{ count: number; }>>
59+
>Promise.reject('some err') : Promise<{ count: number; } | StateMachine<{ count: number; }>>
60+
>Promise.reject : <T = never>(reason?: any) => Promise<T>
61+
>Promise : PromiseConstructor
62+
>reject : <T = never>(reason?: any) => Promise<T>
63+
>'some err' : "some err"
64+
}
65+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
// @target: esnext
2+
// @strict: true
3+
// @noEmit: true
4+
5+
declare class StateMachine<T> {
6+
onDone: (a: T) => void;
7+
}
8+
9+
declare function createMachine<T>(implementations: {
10+
services: Record<string, () => Promise<T> | StateMachine<T>>;
11+
}): void;
12+
13+
createMachine<{ count: number }>({
14+
services: {
15+
test: async () => Promise.reject("some err"),
16+
async test2() {
17+
return Promise.reject("some err");
18+
},
19+
},
20+
});
21+
22+
function fn1(): () => Promise<{ count: number }> | StateMachine<{ count: number }> {
23+
return async () => Promise.reject('some err')
24+
}

0 commit comments

Comments
 (0)