Skip to content

Commit 852b3dc

Browse files
authored
fix(jsii): unable to return Promise<void> (#3752)
The void-check only accounted for the literal `void` type, but failed to account for the `Promise<void>` case. This is now fixed. Fixes #51 --- By submitting this pull request, I confirm that my contribution is made under the terms of the [Apache 2.0 license]. [Apache 2.0 license]: https://www.apache.org/licenses/LICENSE-2.0
1 parent 1cffb04 commit 852b3dc

File tree

3 files changed

+65
-6
lines changed

3 files changed

+65
-6
lines changed

packages/jsii/lib/assembler.ts

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2222,7 +2222,11 @@ export class Assembler implements Emitter {
22222222
protected: _isProtected(symbol) || undefined,
22232223
returns: _isVoid(returnType)
22242224
? undefined
2225-
: this._optionalValue(returnType, declaration.name, 'return type'),
2225+
: this._optionalValue(
2226+
returnType,
2227+
declaration.type ?? declaration.name,
2228+
'return type',
2229+
),
22262230
async: _isPromise(returnType) || undefined,
22272231
static: _isStatic(symbol) || undefined,
22282232
locationInModule: this.declarationLocation(declaration),
@@ -2435,7 +2439,7 @@ export class Assembler implements Emitter {
24352439
{
24362440
...this._optionalValue(
24372441
this._typeChecker.getTypeAtLocation(paramDeclaration),
2438-
paramDeclaration.name,
2442+
paramDeclaration.type ?? paramDeclaration.name,
24392443
'parameter type',
24402444
),
24412445
name: paramSymbol.name,
@@ -2969,7 +2973,22 @@ function _isStatic(symbol: ts.Symbol): boolean {
29692973
);
29702974
}
29712975

2976+
/**
2977+
* Determines whether a given type is void or Promise<void>.
2978+
*
2979+
* @param type the tested type
2980+
*
2981+
* @returns `true` if the type is void or Promise<void>
2982+
*/
29722983
function _isVoid(type: ts.Type): boolean {
2984+
if (_isPromise(type)) {
2985+
const typeRef = type as ts.TypeReference;
2986+
return (
2987+
typeRef.typeArguments != null &&
2988+
typeRef.typeArguments.length === 1 &&
2989+
_isVoid(typeRef.typeArguments[0])
2990+
);
2991+
}
29732992
return (type.flags & ts.TypeFlags.Void) !== 0;
29742993
}
29752994

packages/jsii/test/__snapshots__/negatives.test.js.snap

Lines changed: 4 additions & 4 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

packages/jsii/test/promise.test.ts

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
import { sourceToAssemblyHelper } from '../lib';
2+
3+
// ----------------------------------------------------------------------
4+
test('Promise<void> is a valid return type', () => {
5+
const assembly = sourceToAssemblyHelper(`
6+
export class PromiseMaker {
7+
public static staticPromise(): Promise<void> {
8+
return Promise.resolve();
9+
}
10+
11+
public instancePromise(): Promise<void> {
12+
return Promise.resolve();
13+
}
14+
15+
private constructor() {}
16+
}
17+
`);
18+
19+
expect(assembly.types!['testpkg.PromiseMaker']).toEqual({
20+
assembly: 'testpkg',
21+
fqn: 'testpkg.PromiseMaker',
22+
kind: 'class',
23+
methods: [
24+
{
25+
async: true,
26+
locationInModule: { filename: 'index.ts', line: 3 },
27+
name: 'staticPromise',
28+
static: true,
29+
},
30+
{
31+
async: true,
32+
locationInModule: { filename: 'index.ts', line: 7 },
33+
name: 'instancePromise',
34+
},
35+
],
36+
locationInModule: { filename: 'index.ts', line: 2 },
37+
name: 'PromiseMaker',
38+
symbolId: 'index:PromiseMaker',
39+
});
40+
});

0 commit comments

Comments
 (0)