Skip to content

Commit

Permalink
Implemented TupleType, OptionalType, RestType, TypeOperator (#158)
Browse files Browse the repository at this point in the history
Co-authored-by: Andrii Rodionov <[email protected]>
  • Loading branch information
arodionov and Andrii Rodionov authored Nov 22, 2024
1 parent da44db9 commit c09afff
Show file tree
Hide file tree
Showing 3 changed files with 132 additions and 9 deletions.
49 changes: 45 additions & 4 deletions openrewrite/src/javascript/parser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1270,15 +1270,41 @@ export class JavaScriptParserVisitor {
}

visitTupleType(node: ts.TupleTypeNode) {
return this.visitUnknown(node);
return new JS.Tuple(
randomId(),
this.prefix(node),
Markers.EMPTY,
new JContainer(
Space.EMPTY,
node.elements.length > 0 ?
node.elements.map(p => this.rightPadded(this.convert(p), this.suffix(p)))
.concat(node.elements.hasTrailingComma ? this.rightPadded(this.newJEmpty(), this.prefix(this.findChildNode(node, ts.SyntaxKind.CloseBracketToken)!)) : [])
: [this.rightPadded(this.newJEmpty(this.prefix(this.findChildNode(node, ts.SyntaxKind.CloseBracketToken)!)), Space.EMPTY)], // to handle the case: [/*no*/]
Markers.EMPTY),
this.mapType(node)
);
}

visitOptionalType(node: ts.OptionalTypeNode) {
return this.visitUnknown(node);
return new JS.Unary(
randomId(),
Space.EMPTY,
Markers.EMPTY,
this.leftPadded(this.suffix(node.type), JS.Unary.Type.Optional),
this.visit(node.type),
this.mapType(node)
);
}

visitRestType(node: ts.RestTypeNode) {
return this.visitUnknown(node);
return new JS.Unary(
randomId(),
this.prefix(node),
Markers.EMPTY,
this.leftPadded(Space.EMPTY, JS.Unary.Type.Spread),
this.convert(node.type),
this.mapType(node)
);
}

visitUnionType(node: ts.UnionTypeNode) {
Expand Down Expand Up @@ -1318,7 +1344,22 @@ export class JavaScriptParserVisitor {
}

visitTypeOperator(node: ts.TypeOperatorNode) {
return this.visitUnknown(node);
function mapTypeOperator(operator: ts.SyntaxKind.KeyOfKeyword | ts.SyntaxKind.UniqueKeyword | ts.SyntaxKind.ReadonlyKeyword): JS.TypeOperator.Type | undefined {
switch (operator) {
case ts.SyntaxKind.KeyOfKeyword:
return JS.TypeOperator.Type.KeyOf;
case ts.SyntaxKind.ReadonlyKeyword:
return JS.TypeOperator.Type.ReadOnly;
}
}

return new JS.TypeOperator(
randomId(),
this.prefix(node),
Markers.EMPTY,
mapTypeOperator(node.operator)!,
this.leftPadded(this.prefix(node.type), this.visit(node.type))
);
}

visitIndexedAccessType(node: ts.IndexedAccessTypeNode) {
Expand Down
2 changes: 1 addition & 1 deletion openrewrite/test/javascript/parser/function.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -260,7 +260,7 @@ describe('function mapping', () => {
);
});

test.skip('function with multiple default types', () => {
test('function with multiple default types', () => {
rewriteRun(
//language=typescript
typeScript(`
Expand Down
90 changes: 86 additions & 4 deletions openrewrite/test/javascript/parser/typeAlias.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -94,21 +94,103 @@ describe('type alias mapping', () => {
);
});

test.skip('conditional type', () => {
test('construct function type alias with generic', () => {
rewriteRun(
//language=typescript
typeScript(`
type Flatten<T> = T extends (infer R)[] ? Flatten<R> : T;
type GenericConstructor<T> = new (/*a*/.../*b*/args: any[]) => T;
`)
);
});

test('construct function type alias with generic', () => {
test('tuple type', () => {
rewriteRun(
//language=typescript
typeScript(`
type GenericConstructor<T> = new (/*a*/.../*b*/args: any[]) => T;
type MyTuple = [number, string, boolean];
`)
);
});

test('tuple type with comments', () => {
rewriteRun(
//language=typescript
typeScript(`
type MyTuple = /*a*/[/*b*/number/*c*/, /*d*/string/*e*/, /*f*/boolean/*g*/, /*h*/]/*j*/;
`)
);
});

test('tuple type empty', () => {
rewriteRun(
//language=typescript
typeScript(`
type MyTuple = [/*a*/];
`)
);
});

test('nested tuple type', () => {
rewriteRun(
//language=typescript
typeScript(`
type NestedTuple = [number, [string, boolean]];
`)
);
});

test('optional tuple type', () => {
rewriteRun(
//language=typescript
typeScript(`
type OptionalTuple = [string, /*a*/number/*b*/?/*c*/];
`)
);
});

test('tuple rest type', () => {
rewriteRun(
//language=typescript
typeScript(`
type FlexibleTuple = [string, ...number[]];
`)
);
});

test('readonly operator tuple type', () => {
rewriteRun(
//language=typescript
typeScript(`
type ReadonlyTuple = readonly [string, number];
`)
);
});

test('readonly operator tuple type with comments', () => {
rewriteRun(
//language=typescript
typeScript(`
type ReadonlyTuple = /*a*/keyof /*b*/ [string, number];
`)
);
});

test.skip('basic conditional type', () => {
rewriteRun(
//language=typescript
typeScript(`
type IsString<T> = T extends string ? "Yes" : "No";
`)
);
});

test.skip('conditional type', () => {
rewriteRun(
//language=typescript
typeScript(`
type Flatten<T> = T extends (infer R)[] ? Flatten<R> : T;
`)
);
});

});

0 comments on commit c09afff

Please sign in to comment.