Skip to content

Commit

Permalink
fix(typeof-alias-export): make sure alias exports will be transformed…
Browse files Browse the repository at this point in the history
… correctly (#214)
  • Loading branch information
uittorio committed Feb 2, 2020
1 parent 93c047c commit 27ae136
Show file tree
Hide file tree
Showing 4 changed files with 53 additions and 14 deletions.
48 changes: 34 additions & 14 deletions src/transformer/descriptor/module/module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { TypescriptHelper } from '../helper/helper';
import { GetMockPropertiesFromDeclarations } from '../mock/mockProperties';
import { PropertyLike } from '../mock/propertyLike';
import { GetTypeQueryDescriptorFromDeclaration } from '../typeQuery/typeQuery';
type ExternalSource = ts.SourceFile | ts.ModuleDeclaration;

export function GetModuleDescriptor(node: ts.NamedDeclaration, scope: Scope): ts.Expression {
const typeChecker: ts.TypeChecker = TypeChecker();
Expand All @@ -14,21 +15,40 @@ export function GetModuleDescriptor(node: ts.NamedDeclaration, scope: Scope): ts
const symbol: ts.Symbol = typeChecker.getAliasedSymbol(symbolAlias);
const externalModuleDeclaration: ts.NamedDeclaration = symbol.declarations[0];

if (ts.isSourceFile(externalModuleDeclaration) || ts.isModuleDeclaration(externalModuleDeclaration)) {
const moduleExports: ts.Symbol[] = typeChecker.getExportsOfModule(symbol);

const properties: PropertyLike[] = moduleExports.map((prop: ts.Symbol): PropertyLike => {
const originalSymbol: ts.Symbol = TypescriptHelper.GetAliasedSymbolSafe(prop);
const originalDeclaration: ts.NamedDeclaration = originalSymbol.declarations[0];
const declaration: ts.Declaration = prop.declarations[0];
if (ts.isExportAssignment(declaration)) {
return TypescriptCreator.createProperty('default', ts.createTypeQueryNode(originalDeclaration.name as ts.Identifier));
}
return TypescriptCreator.createProperty(originalDeclaration.name as ts.Identifier, ts.createTypeQueryNode(originalDeclaration.name as ts.Identifier));
});

return GetMockPropertiesFromDeclarations(properties, [], scope);
if (isExternalSource(externalModuleDeclaration)) {
return GetPropertiesFromSourceFileOrModuleDeclaration(externalModuleDeclaration, symbol, scope);
}

return GetTypeQueryDescriptorFromDeclaration(externalModuleDeclaration, scope);
}

function isExternalSource(declaration: ts.Node): declaration is ExternalSource {
return ts.isSourceFile(declaration) || ts.isModuleDeclaration(declaration);
}

function GetPropertiesFromSourceFileOrModuleDeclaration(sourceFile: ExternalSource, symbol: ts.Symbol, scope: Scope): ts.Expression {
const typeChecker: ts.TypeChecker = TypeChecker();
const moduleExports: ts.Symbol[] = typeChecker.getExportsOfModule(symbol);

const properties: PropertyLike[] = moduleExports.map((prop: ts.Symbol): PropertyLike => {
const originalSymbol: ts.Symbol = TypescriptHelper.GetAliasedSymbolSafe(prop);
const originalDeclaration: ts.NamedDeclaration = originalSymbol.declarations[0];
const declaration: ts.Declaration = prop.declarations[0];

if (ts.isExportAssignment(declaration)) {
return TypescriptCreator.createProperty('default', ts.createTypeQueryNode(originalDeclaration.name as ts.Identifier));
}

if (ts.isExportSpecifier(declaration) && ts.isSourceFile(originalDeclaration)) {
const exportSpecifierSymbol: ts.Symbol = typeChecker.getSymbolAtLocation(declaration.name);
const exportSpecifierAliasSymbol: ts.Symbol = typeChecker.getAliasedSymbol(exportSpecifierSymbol);
const exportSpecifierProperties: ts.Expression = GetPropertiesFromSourceFileOrModuleDeclaration(originalDeclaration, exportSpecifierAliasSymbol, scope);

return TypescriptCreator.createPropertyWitInitializer(declaration.name, exportSpecifierProperties);
}

return TypescriptCreator.createProperty(originalDeclaration.name as ts.Identifier, ts.createTypeQueryNode(originalDeclaration.name as ts.Identifier));
});

return GetMockPropertiesFromDeclarations(properties, [], scope);
}
4 changes: 4 additions & 0 deletions src/transformer/helper/creator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,10 @@ export namespace TypescriptCreator {
return ts.createProperty([], [], propertyName, undefined, type, undefined);
}

export function createPropertyWitInitializer(propertyName: string | PropertyName, initializer: ts.Expression): ts.PropertyDeclaration {
return ts.createProperty([], [], propertyName, undefined, undefined, initializer);
}

export function createParameter(parameterName: string): ts.ParameterDeclaration {
return ts.createParameter(
undefined,
Expand Down
12 changes: 12 additions & 0 deletions test/transformer/descriptor/typeQuery/typeQueryOfExports.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import { createMock } from 'ts-auto-mock';
import exportAlias = require('../utils/export/exportAlias');

describe('typeQuery exports ', () => {
describe('for export aliases ', () => {
it('should assign all the types as an object', () => {
const type: typeof exportAlias = createMock<typeof exportAlias>();

expect(new type.types.Class().a).toBe('');
});
});
});
3 changes: 3 additions & 0 deletions test/transformer/descriptor/utils/export/exportAlias.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import * as allTypes from '../classes/class';

export { allTypes as types };

0 comments on commit 27ae136

Please sign in to comment.