Skip to content
This repository has been archived by the owner on Oct 5, 2021. It is now read-only.

Commit

Permalink
fix(core): make Typewiz robust to errors from .toString() user code
Browse files Browse the repository at this point in the history
fix #84
  • Loading branch information
urish committed Nov 28, 2018
1 parent aa83a02 commit a9f5642
Show file tree
Hide file tree
Showing 2 changed files with 60 additions and 36 deletions.
11 changes: 11 additions & 0 deletions packages/typewiz-core/src/type-collector-snippet.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,17 @@ describe('type-collector', () => {
);
});

it('should gracefully deal with toString() method throwing an error', () => {
function f() {
/* noop */
}
f.toString = () => {
throw new Error('Dont call this method');
};

expect($_$twiz.typeName(f)).toBe('Function');
});

/* tslint:enable:only-arrow-functions*/
});

Expand Down
85 changes: 49 additions & 36 deletions packages/typewiz-core/src/type-collector-snippet.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,42 +47,10 @@ export function getTypeName(value: any, nest = 0): string | null {
return `Array<${itemTypes.sort().join('|')}>`;
}
if (value instanceof Function) {
let argsStr: string = value.toString().split('=>')[0];

// make sure argsStr is in a form of (arg1,arg2) for the following cases
// fn = a => 3
// fn = (a) => 3
// function fn(a) { return 3 }

argsStr = argsStr.includes('(') ? (argsStr.match(/\(.*?\)/gi) || '()')[0] : `(${argsStr})`;
const args: string[] = argsStr
.replace(/[()]/g, '')
.split(',')
.filter((e: string) => e !== '');

const typedArgs = args.map((arg) => {
let [name] = arg.split('=');
name = name.trim();

if (name.includes('[')) {
const nakedName = name.replace(/\[|\]/gi, '').trim();
name = `${nakedName}Array`;
return `${name}: any`;
}
if (name.includes('{')) {
const nakedName = name.replace(/\{|\}/gi, '').trim();
name = `${nakedName}Object: {${nakedName}: any}`;
return `${name}`;
}
if (name.includes('...')) {
name = `${name}Array: any[]`;
return `${name}`;
}

return `${name}: any`;
});

return `(${typedArgs}) => any`;
const result = getFunctionType(value);
if (result) {
return result;
}
}
if (value.constructor && value.constructor.name) {
const { name } = value.constructor;
Expand All @@ -101,6 +69,51 @@ export function getTypeName(value: any, nest = 0): string | null {
}
}

function getFunctionType(value: any): string | undefined {

This comment has been minimized.

Copy link
@BridgeAR

BridgeAR Jul 25, 2019

The return type is always string and never undefined, if I am not mistaken.
The error case returns 'Function' and the other case always returns a string as well.

This comment has been minimized.

Copy link
@urish

urish Jul 26, 2019

Author Collaborator

good catch

let argsStr: string = '';
try {
argsStr = value.toString().split('=>')[0];
} catch (err) {
// toString() could throw an error
return 'Function';
}

// make sure argsStr is in a form of (arg1,arg2) for the following cases
// fn = a => 3
// fn = (a) => 3
// function fn(a) { return 3 }

argsStr = argsStr.includes('(') ? (argsStr.match(/\(.*?\)/gi) || '()')[0] : `(${argsStr})`;
const args: string[] = argsStr
.replace(/[()]/g, '')
.split(',')
.filter((e: string) => e !== '');

const typedArgs = args.map((arg) => {
let [name] = arg.split('=');
name = name.trim();

if (name.includes('[')) {
const nakedName = name.replace(/\[|\]/gi, '').trim();
name = `${nakedName}Array`;
return `${name}: any`;
}
if (name.includes('{')) {
const nakedName = name.replace(/\{|\}/gi, '').trim();
name = `${nakedName}Object: {${nakedName}: any}`;
return `${name}`;
}
if (name.includes('...')) {
name = `${name}Array: any[]`;
return `${name}`;
}

return `${name}: any`;
});

return `(${typedArgs}) => any`;

This comment has been minimized.

Copy link
@BridgeAR

BridgeAR Jul 25, 2019

It would be more robust not to rely on Array#toString in this case.

}

function getObjectTypes(obj: any, nest: number): string {
const keys = Object.keys(obj).sort();
if (keys.length === 0) {
Expand Down

0 comments on commit a9f5642

Please sign in to comment.