Skip to content

Commit

Permalink
feat(ts): add flattenSubclassesToUnion param (#78)
Browse files Browse the repository at this point in the history
Signed-off-by: Matt Roberts <[email protected]>
  • Loading branch information
mttrbrts authored Nov 24, 2023
1 parent e38396e commit af903c3
Show file tree
Hide file tree
Showing 2 changed files with 32 additions and 2 deletions.
12 changes: 10 additions & 2 deletions lib/codegen/fromcto/typescript/typescriptvisitor.js
Original file line number Diff line number Diff line change
Expand Up @@ -234,7 +234,6 @@ class TypescriptVisitor {
if (field.isOptional()) {
optional = '?';
}

const isEnumRef = field.isPrimitive() ? false
: field.getParent().getModelFile().getModelManager().getType(field.getFullyQualifiedTypeName()).isEnum();

Expand All @@ -249,7 +248,16 @@ class TypescriptVisitor {
decoratorArguments.length > 0 && (literal = ` = ${field.getType()}.${decoratorArguments}`);
}

const tsType = this.toTsType(field.getType(), !isEnumRef && !hasUnion && !isMapRef, hasUnion);
let tsType = this.toTsType(field.getType(), !isEnumRef && !hasUnion && !isMapRef, hasUnion);

// If there exists direct subclasses for this field's declaration then use the union type instead
if (!!parameters.flattenSubclassesToUnion & !field.isPrimitive()) {
const subclasses = field.getParent().getModelFile().getModelManager().getType(field.getFullyQualifiedTypeName()).getDirectSubclasses();
if (subclasses && subclasses.length > 0) {
const useUnion = !(isEnumRef || isMapRef);
tsType = this.toTsType(field.getType(), !useUnion, useUnion);
}
}

if (literal) {
parameters.fileWriter.writeLine(1, field.getName() + literal + ';');
Expand Down
22 changes: 22 additions & 0 deletions test/codegen/fromcto/typescript/typescriptvisitor.js
Original file line number Diff line number Diff line change
Expand Up @@ -624,6 +624,28 @@ describe('TypescriptVisitor', function () {

param.fileWriter.writeLine.withArgs(1, 'literalTest = EnumType.MyEnumValue;').calledOnce.should.be.ok;
});

it('should write a line for field name using a union type when the flattenSubclassesToUnion parameter is set', () => {
const mockField = sinon.createStubInstance(Field);
mockField.isPrimitive.returns(false);
mockField.getName.returns('flattenSubclassesTest');
mockField.getType.returns('Animal');
mockField.getDecorators.returns([]);

const mockModelManager = sinon.createStubInstance(ModelManager);
const mockModelFile = sinon.createStubInstance(ModelFile);
const mockClassDeclaration = sinon.createStubInstance(ClassDeclaration);
mockClassDeclaration.getDirectSubclasses.returns(['blah']); // Not valid, but sufficient for this test

mockModelManager.getType.returns(mockClassDeclaration);
mockClassDeclaration.isEnum.returns(false);
mockModelFile.getModelManager.returns(mockModelManager);
mockClassDeclaration.getModelFile.returns(mockModelFile);
mockField.getParent.returns(mockClassDeclaration);
typescriptVisitor.visitField(mockField, { ...param, flattenSubclassesToUnion: true });

param.fileWriter.writeLine.withArgs(1, 'flattenSubclassesTest: AnimalUnion;').calledOnce.should.be.ok;
});
});

describe('visitEnumValueDeclaration', () => {
Expand Down

0 comments on commit af903c3

Please sign in to comment.