Skip to content

Commit

Permalink
function types: optional and vararg arguments.
Browse files Browse the repository at this point in the history
Previously, tsickle would support optional and varag arguments in
function declarations (`@param` tags etc), but not in pure function
types.
  • Loading branch information
mprobst committed Nov 10, 2017
1 parent 0e6463b commit d004209
Show file tree
Hide file tree
Showing 3 changed files with 27 additions and 6 deletions.
26 changes: 22 additions & 4 deletions src/type-translator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -589,6 +589,7 @@ export class TypeTranslator {

/** Converts a ts.Signature (function signature) to a Closure function type. */
private signatureToClosure(sig: ts.Signature): string {
// TODO(martinprobst): Consider harmonizing some overlap with emitFunctionType in tsickle.ts.
const params = this.convertParams(sig);
let typeStr = `function(${params.join(', ')})`;

Expand All @@ -601,10 +602,27 @@ export class TypeTranslator {
}

private convertParams(sig: ts.Signature): string[] {
return sig.parameters.map(param => {
const paramType = this.typeChecker.getTypeOfSymbolAtLocation(param, this.node);
return this.translate(paramType);
});
const paramTypes: string[] = [];
// The Signature itself does not include information on optional and var arg parameters.
// Use its declaration to recover that information.
const decl = sig.declaration;
for (let i = 0; i < sig.parameters.length; i ++ ) {
const param = sig.parameters[i];

const paramDecl = decl.parameters[i];
const optional = !!paramDecl.questionToken;
const varArgs = !!paramDecl.dotDotDotToken;
let paramType = this.typeChecker.getTypeOfSymbolAtLocation(param, this.node);
if (varArgs) {
const typeRef = paramType as ts.TypeReference;
paramType = typeRef.typeArguments![0];
}
let typeStr = this.translate(paramType);
if (varArgs) typeStr = '...'+typeStr;
if (optional) typeStr = typeStr + '=';
paramTypes.push(typeStr);
}
return paramTypes;
}

warn(msg: string) {
Expand Down
2 changes: 2 additions & 0 deletions test_files/type/type.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ let /** @type {{optional: (undefined|string|boolean)}} */ typeOptionalUnion = {}
let /** @type {function(): void} */ typeFunc = function () { };
let /** @type {function(number, ?): string} */ typeFunc2 = function (a, b) { return ''; };
let /** @type {function(number, function(number): string): string} */ typeFunc3 = function (x, cb) { return ''; };
let /** @type {function(number, (undefined|!Object)=): string} */ typeFuncOptionalArg;
let /** @type {function(number, ...number): void} */ typeFuncVarArgs;
/**
* @param {function(number): number} callback
* @return {void}
Expand Down
5 changes: 3 additions & 2 deletions test_files/type/type.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,9 @@ let typeOptionalUnion: {optional?: string|boolean} = {};

let typeFunc: () => void = function() {};
let typeFunc2: (a: number, b: any) => string = function(a, b) { return ''; };
let typeFunc3: (x: number, callback: (x: number) => string) => string = function(x, cb) { return ''; }
// TODO: let typeFunc4: (a: number, ...args: number[]) => void;
let typeFunc3: (x: number, callback: (x: number) => string) => string = function(x, cb) { return ''; };
let typeFuncOptionalArg: (a: number, b?: {}) => string;
let typeFuncVarArgs: (a: number, ...args: number[]) => void;

function typeCallback(callback: (val: number) => number) { }
typeCallback(val => val + 1);
Expand Down

0 comments on commit d004209

Please sign in to comment.