Skip to content

Commit

Permalink
fix(jsii): unable to return Promise<void> (#3752)
Browse files Browse the repository at this point in the history
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
  • Loading branch information
RomainMuller committed Sep 19, 2022
1 parent 1cffb04 commit 852b3dc
Show file tree
Hide file tree
Showing 3 changed files with 65 additions and 6 deletions.
23 changes: 21 additions & 2 deletions packages/jsii/lib/assembler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2222,7 +2222,11 @@ export class Assembler implements Emitter {
protected: _isProtected(symbol) || undefined,
returns: _isVoid(returnType)
? undefined
: this._optionalValue(returnType, declaration.name, 'return type'),
: this._optionalValue(
returnType,
declaration.type ?? declaration.name,
'return type',
),
async: _isPromise(returnType) || undefined,
static: _isStatic(symbol) || undefined,
locationInModule: this.declarationLocation(declaration),
Expand Down Expand Up @@ -2435,7 +2439,7 @@ export class Assembler implements Emitter {
{
...this._optionalValue(
this._typeChecker.getTypeAtLocation(paramDeclaration),
paramDeclaration.name,
paramDeclaration.type ?? paramDeclaration.name,
'parameter type',
),
name: paramSymbol.name,
Expand Down Expand Up @@ -2969,7 +2973,22 @@ function _isStatic(symbol: ts.Symbol): boolean {
);
}

/**
* Determines whether a given type is void or Promise<void>.
*
* @param type the tested type
*
* @returns `true` if the type is void or Promise<void>
*/
function _isVoid(type: ts.Type): boolean {
if (_isPromise(type)) {
const typeRef = type as ts.TypeReference;
return (
typeRef.typeArguments != null &&
typeRef.typeArguments.length === 1 &&
_isVoid(typeRef.typeArguments[0])
);
}
return (type.flags & ts.TypeFlags.Void) !== 0;
}

Expand Down
8 changes: 4 additions & 4 deletions packages/jsii/test/__snapshots__/negatives.test.js.snap

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

40 changes: 40 additions & 0 deletions packages/jsii/test/promise.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import { sourceToAssemblyHelper } from '../lib';

// ----------------------------------------------------------------------
test('Promise<void> is a valid return type', () => {
const assembly = sourceToAssemblyHelper(`
export class PromiseMaker {
public static staticPromise(): Promise<void> {
return Promise.resolve();
}
public instancePromise(): Promise<void> {
return Promise.resolve();
}
private constructor() {}
}
`);

expect(assembly.types!['testpkg.PromiseMaker']).toEqual({
assembly: 'testpkg',
fqn: 'testpkg.PromiseMaker',
kind: 'class',
methods: [
{
async: true,
locationInModule: { filename: 'index.ts', line: 3 },
name: 'staticPromise',
static: true,
},
{
async: true,
locationInModule: { filename: 'index.ts', line: 7 },
name: 'instancePromise',
},
],
locationInModule: { filename: 'index.ts', line: 2 },
name: 'PromiseMaker',
symbolId: 'index:PromiseMaker',
});
});

0 comments on commit 852b3dc

Please sign in to comment.