Skip to content

Commit 14e8de3

Browse files
committed
fix(typescript): Handle invalid type names
1 parent 36e5788 commit 14e8de3

File tree

2 files changed

+61
-6
lines changed

2 files changed

+61
-6
lines changed

plugins/typescript/src/core/schemaToTypeAliasDeclaration.test.ts

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -946,6 +946,30 @@ describe("schemaToTypeAliasDeclaration", () => {
946946
`);
947947
});
948948

949+
it("should generate valid identifier from number name", () => {
950+
const schema: SchemaObject = {};
951+
952+
expect(printSchema(schema, "200")).toMatchInlineSnapshot(`
953+
"export type TwoHundred = void;"
954+
`);
955+
});
956+
957+
it("should generate valid identifier from symbol name", () => {
958+
const schema: SchemaObject = {};
959+
960+
expect(printSchema(schema, "-")).toMatchInlineSnapshot(`
961+
"export type _ = void;"
962+
`);
963+
});
964+
965+
it("should generate valid identifier from invalid name", () => {
966+
const schema: SchemaObject = {};
967+
968+
expect(printSchema(schema, "🙂")).toMatchInlineSnapshot(`
969+
"export type _ = void;"
970+
`);
971+
});
972+
949973
it("should generate a `never` if the combined type is broken", () => {
950974
const schema: SchemaObject = {
951975
allOf: [{ type: "string" }, { type: "number" }],

plugins/typescript/src/core/schemaToTypeAliasDeclaration.ts

Lines changed: 37 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,12 @@ import {
1111
} from "openapi3-ts/oas30";
1212
import { singular } from "pluralize";
1313
import { isValidIdentifier } from "tsutils";
14-
import ts, { factory as f } from "typescript";
14+
import ts, {
15+
factory as f,
16+
isIdentifierPart,
17+
isIdentifierStart,
18+
} from "typescript";
19+
import { convertNumberToWord } from "../utils/getEnumProperties";
1520
import { getReferenceSchema } from "./getReference";
1621

1722
type RemoveIndex<T> = {
@@ -56,11 +61,37 @@ export const schemaToTypeAliasDeclaration = (
5661
const jsDocNode = isSchemaObject(schema)
5762
? getJSDocComment(schema, context)
5863
: undefined;
64+
65+
let identifier = pascal(name);
66+
67+
if (identifier.length > 0 && !isNaN(Number(identifier))) {
68+
// If the identifier can be cast to a number, convert it to a word.
69+
identifier = pascal(convertNumberToWord(Number(identifier)));
70+
} else {
71+
// If the identifier does not start with a valid character but valid identifier part, prefix it with an underscore.
72+
if (
73+
!isIdentifierStart(identifier.charCodeAt(0), ts.ScriptTarget.Latest) &&
74+
isIdentifierPart(identifier.charCodeAt(0), ts.ScriptTarget.Latest)
75+
) {
76+
identifier = `_${identifier}`;
77+
}
78+
79+
// If the identifier is still not valid, remove invalid characters.
80+
if (!isValidIdentifier(identifier)) {
81+
identifier = identifier.replace(/[^a-zA-Z0-9_]/g, "");
82+
}
83+
84+
// If the identifier is now empty, set it to "_".
85+
if (identifier.length === 0) {
86+
identifier = "_";
87+
}
88+
}
89+
5990
const declarationNode = f.createTypeAliasDeclaration(
6091
[f.createModifier(ts.SyntaxKind.ExportKeyword)],
61-
pascal(name),
92+
identifier,
6293
undefined,
63-
getType(schema, context, name)
94+
getType(schema, context, identifier)
6495
);
6596

6697
return jsDocNode ? [jsDocNode, declarationNode] : [declarationNode];
@@ -89,10 +120,10 @@ export const getType = (
89120

90121
let refNode: ts.TypeNode = f.createTypeReferenceNode(
91122
namespace === context.currentComponent
92-
? f.createIdentifier(pascal(name))
123+
? f.createIdentifier(name)
93124
: f.createQualifiedName(
94125
f.createIdentifier(pascal(namespace)),
95-
f.createIdentifier(pascal(name))
126+
f.createIdentifier(name)
96127
)
97128
);
98129

@@ -174,7 +205,7 @@ export const getType = (
174205
if (schema.enum) {
175206
if (isNodeEnum) {
176207
return f.createUnionTypeNode([
177-
f.createTypeReferenceNode(f.createIdentifier(pascal(name || ""))),
208+
f.createTypeReferenceNode(f.createIdentifier(name || "")),
178209
...(schema.nullable ? [f.createLiteralTypeNode(f.createNull())] : []),
179210
]);
180211
}

0 commit comments

Comments
 (0)