diff --git a/docs/generators/typescript-angular.md b/docs/generators/typescript-angular.md
index 59a2f4dd9488..2def608c0dc1 100644
--- a/docs/generators/typescript-angular.md
+++ b/docs/generators/typescript-angular.md
@@ -75,20 +75,42 @@ These options may be applied as additional-properties (cli) or configOptions (pl
- Array
+- Awaited
- Blob
- Boolean
+- Capitalize
+- ConstructorParameters
- Date
- Double
- Error
+- Exclude
+- Extract
- File
- Float
+- InstanceType
- Integer
- Long
+- Lowercase
- Map
+- NoInfer
+- NonNullable
- Object
+- Omit
+- OmitThisParameter
+- Parameters
+- Partial
+- Pick
+- Readonly
- ReadonlyArray
+- Record
+- Required
+- ReturnType
- Set
- String
+- ThisParameterType
+- ThisType
+- Uncapitalize
+- Uppercase
- any
- boolean
- number
diff --git a/docs/generators/typescript-aurelia.md b/docs/generators/typescript-aurelia.md
index d5bf4e06d987..5e1add4c4842 100644
--- a/docs/generators/typescript-aurelia.md
+++ b/docs/generators/typescript-aurelia.md
@@ -55,19 +55,41 @@ These options may be applied as additional-properties (cli) or configOptions (pl
- Array
+- Awaited
- Boolean
+- Capitalize
+- ConstructorParameters
- Date
- Double
- Error
+- Exclude
+- Extract
- File
- Float
+- InstanceType
- Integer
- Long
+- Lowercase
- Map
+- NoInfer
+- NonNullable
- Object
+- Omit
+- OmitThisParameter
+- Parameters
+- Partial
+- Pick
+- Readonly
- ReadonlyArray
+- Record
+- Required
+- ReturnType
- Set
- String
+- ThisParameterType
+- ThisType
+- Uncapitalize
+- Uppercase
- any
- boolean
- number
diff --git a/docs/generators/typescript-axios.md b/docs/generators/typescript-axios.md
index cd045987765e..66df7b84a90d 100644
--- a/docs/generators/typescript-axios.md
+++ b/docs/generators/typescript-axios.md
@@ -66,19 +66,41 @@ These options may be applied as additional-properties (cli) or configOptions (pl
- Array
+- Awaited
- Boolean
+- Capitalize
+- ConstructorParameters
- Date
- Double
- Error
+- Exclude
+- Extract
- File
- Float
+- InstanceType
- Integer
- Long
+- Lowercase
- Map
+- NoInfer
+- NonNullable
- Object
+- Omit
+- OmitThisParameter
+- Parameters
+- Partial
+- Pick
+- Readonly
- ReadonlyArray
+- Record
+- Required
+- ReturnType
- Set
- String
+- ThisParameterType
+- ThisType
+- Uncapitalize
+- Uppercase
- any
- boolean
- number
diff --git a/docs/generators/typescript-fetch.md b/docs/generators/typescript-fetch.md
index c2fc7b0bec45..3019201de917 100644
--- a/docs/generators/typescript-fetch.md
+++ b/docs/generators/typescript-fetch.md
@@ -66,19 +66,41 @@ These options may be applied as additional-properties (cli) or configOptions (pl
- Array
+- Awaited
- Boolean
+- Capitalize
+- ConstructorParameters
- Date
- Double
- Error
+- Exclude
+- Extract
- File
- Float
+- InstanceType
- Integer
- Long
+- Lowercase
- Map
+- NoInfer
+- NonNullable
- Object
+- Omit
+- OmitThisParameter
+- Parameters
+- Partial
+- Pick
+- Readonly
- ReadonlyArray
+- Record
+- Required
+- ReturnType
- Set
- String
+- ThisParameterType
+- ThisType
+- Uncapitalize
+- Uppercase
- any
- boolean
- number
diff --git a/docs/generators/typescript-inversify.md b/docs/generators/typescript-inversify.md
index 9daedb0707a6..a98d919447b9 100644
--- a/docs/generators/typescript-inversify.md
+++ b/docs/generators/typescript-inversify.md
@@ -60,20 +60,42 @@ These options may be applied as additional-properties (cli) or configOptions (pl
- Array
+- Awaited
- Blob
- Boolean
+- Capitalize
+- ConstructorParameters
- Date
- Double
- Error
+- Exclude
+- Extract
- File
- Float
+- InstanceType
- Integer
- Long
+- Lowercase
- Map
+- NoInfer
+- NonNullable
- Object
+- Omit
+- OmitThisParameter
+- Parameters
+- Partial
+- Pick
+- Readonly
- ReadonlyArray
+- Record
+- Required
+- ReturnType
- Set
- String
+- ThisParameterType
+- ThisType
+- Uncapitalize
+- Uppercase
- any
- boolean
- number
diff --git a/docs/generators/typescript-jquery.md b/docs/generators/typescript-jquery.md
index 148d28e5f609..2d7332baa12d 100644
--- a/docs/generators/typescript-jquery.md
+++ b/docs/generators/typescript-jquery.md
@@ -57,19 +57,41 @@ These options may be applied as additional-properties (cli) or configOptions (pl
- Array
+- Awaited
- Boolean
+- Capitalize
+- ConstructorParameters
- Date
- Double
- Error
+- Exclude
+- Extract
- File
- Float
+- InstanceType
- Integer
- Long
+- Lowercase
- Map
+- NoInfer
+- NonNullable
- Object
+- Omit
+- OmitThisParameter
+- Parameters
+- Partial
+- Pick
+- Readonly
- ReadonlyArray
+- Record
+- Required
+- ReturnType
- Set
- String
+- ThisParameterType
+- ThisType
+- Uncapitalize
+- Uppercase
- any
- boolean
- number
diff --git a/docs/generators/typescript-nestjs.md b/docs/generators/typescript-nestjs.md
index 47037f98f6b0..4469d54d2194 100644
--- a/docs/generators/typescript-nestjs.md
+++ b/docs/generators/typescript-nestjs.md
@@ -66,20 +66,42 @@ These options may be applied as additional-properties (cli) or configOptions (pl
- Array
+- Awaited
- Blob
- Boolean
+- Capitalize
+- ConstructorParameters
- Date
- Double
- Error
+- Exclude
+- Extract
- File
- Float
+- InstanceType
- Integer
- Long
+- Lowercase
- Map
+- NoInfer
+- NonNullable
- Object
+- Omit
+- OmitThisParameter
+- Parameters
+- Partial
+- Pick
+- Readonly
- ReadonlyArray
+- Record
+- Required
+- ReturnType
- Set
- String
+- ThisParameterType
+- ThisType
+- Uncapitalize
+- Uppercase
- any
- boolean
- number
diff --git a/docs/generators/typescript-node.md b/docs/generators/typescript-node.md
index 00faa993cbec..a92f830046fa 100644
--- a/docs/generators/typescript-node.md
+++ b/docs/generators/typescript-node.md
@@ -56,23 +56,45 @@ These options may be applied as additional-properties (cli) or configOptions (pl
- Array
+- Awaited
- Boolean
- Buffer
+- Capitalize
+- ConstructorParameters
- Date
- Double
- Error
+- Exclude
+- Extract
- File
- Float
+- InstanceType
- Integer
- Long
+- Lowercase
- Map
+- NoInfer
+- NonNullable
- Object
+- Omit
+- OmitThisParameter
+- Parameters
+- Partial
+- Pick
- ReadStream
+- Readonly
- ReadonlyArray
+- Record
- RequestDetailedFile
- RequestFile
+- Required
+- ReturnType
- Set
- String
+- ThisParameterType
+- ThisType
+- Uncapitalize
+- Uppercase
- any
- boolean
- number
diff --git a/docs/generators/typescript-redux-query.md b/docs/generators/typescript-redux-query.md
index 9b7a130dc81a..8d1466566dfa 100644
--- a/docs/generators/typescript-redux-query.md
+++ b/docs/generators/typescript-redux-query.md
@@ -58,19 +58,41 @@ These options may be applied as additional-properties (cli) or configOptions (pl
- Array
+- Awaited
- Boolean
+- Capitalize
+- ConstructorParameters
- Date
- Double
- Error
+- Exclude
+- Extract
- File
- Float
+- InstanceType
- Integer
- Long
+- Lowercase
- Map
+- NoInfer
+- NonNullable
- Object
+- Omit
+- OmitThisParameter
+- Parameters
+- Partial
+- Pick
+- Readonly
- ReadonlyArray
+- Record
+- Required
+- ReturnType
- Set
- String
+- ThisParameterType
+- ThisType
+- Uncapitalize
+- Uppercase
- any
- boolean
- number
diff --git a/docs/generators/typescript-rxjs.md b/docs/generators/typescript-rxjs.md
index 61c23805c8cf..b5af5b3a6843 100644
--- a/docs/generators/typescript-rxjs.md
+++ b/docs/generators/typescript-rxjs.md
@@ -57,20 +57,42 @@ These options may be applied as additional-properties (cli) or configOptions (pl
- Array
+- Awaited
- Blob
- Boolean
+- Capitalize
+- ConstructorParameters
- Date
- Double
- Error
+- Exclude
+- Extract
- File
- Float
+- InstanceType
- Integer
- Long
+- Lowercase
- Map
+- NoInfer
+- NonNullable
- Object
+- Omit
+- OmitThisParameter
+- Parameters
+- Partial
+- Pick
+- Readonly
- ReadonlyArray
+- Record
+- Required
+- ReturnType
- Set
- String
+- ThisParameterType
+- ThisType
+- Uncapitalize
+- Uppercase
- any
- boolean
- number
diff --git a/docs/generators/typescript.md b/docs/generators/typescript.md
index d53ba13a6b81..0b11b1034a94 100644
--- a/docs/generators/typescript.md
+++ b/docs/generators/typescript.md
@@ -63,19 +63,41 @@ These options may be applied as additional-properties (cli) or configOptions (pl
- Array
+- Awaited
- Boolean
+- Capitalize
+- ConstructorParameters
- Date
- Double
- Error
+- Exclude
+- Extract
- File
- Float
+- InstanceType
- Integer
- Long
+- Lowercase
- Map
+- NoInfer
+- NonNullable
- Object
+- Omit
+- OmitThisParameter
+- Parameters
+- Partial
+- Pick
+- Readonly
- ReadonlyArray
+- Record
+- Required
+- ReturnType
- Set
- String
+- ThisParameterType
+- ThisType
+- Uncapitalize
+- Uppercase
- any
- boolean
- number
diff --git a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/AbstractTypeScriptClientCodegen.java b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/AbstractTypeScriptClientCodegen.java
index a57a9f991e9d..69a5a6240a22 100644
--- a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/AbstractTypeScriptClientCodegen.java
+++ b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/AbstractTypeScriptClientCodegen.java
@@ -304,6 +304,14 @@ public AbstractTypeScriptClientCodegen() {
// Typescript reserved words
"abstract", "await", "boolean", "break", "byte", "case", "catch", "char", "class", "const", "continue", "debugger", "default", "delete", "do", "double", "else", "enum", "export", "extends", "false", "final", "finally", "float", "for", "function", "goto", "if", "implements", "import", "in", "instanceof", "int", "interface", "let", "long", "native", "new", "null", "package", "private", "protected", "public", "return", "short", "static", "super", "switch", "synchronized", "this", "throw", "transient", "true", "try", "typeof", "var", "void", "volatile", "while", "with", "yield"));
+ Set utilityTypes = new HashSet<>(Arrays.asList(
+ "Awaited","Partial","Required","Readonly","Record","Pick","Omit","Exclude","Extract","NonNullable",
+ "Parameters","ConstructorParameters","ReturnType","InstanceType","NoInfer","ThisParameterType",
+ "OmitThisParameter","ThisType","Uppercase","Lowercase","Capitalize","Uncapitalize")
+ );
+ defaultIncludes = new HashSet<>();
+ defaultIncludes.addAll(utilityTypes);
+
languageSpecificPrimitives = new HashSet<>(Arrays.asList(
"string",
"String",
@@ -325,6 +333,7 @@ public AbstractTypeScriptClientCodegen() {
"object",
"Set"
));
+ languageSpecificPrimitives.addAll(utilityTypes);
languageGenericTypes = new HashSet<>(Collections.singletonList(
"Array"
@@ -805,7 +814,8 @@ public String getSchemaType(Schema p) {
return openAPIType;
} else if (typeMapping.containsKey(openAPIType)) {
type = typeMapping.get(openAPIType);
- if (languageSpecificPrimitives.contains(type)) {
+ String typeWithoutGeneric = typeWithoutGeneric(type);
+ if (languageSpecificPrimitives.contains(typeWithoutGeneric)) {
return type;
}
} else {
@@ -1157,6 +1167,16 @@ protected List getTypesFromSchemas(List schemas) {
}).distinct().collect(Collectors.toList());
}
+ @Override
+ protected boolean needToImport(String type) {
+ return super.needToImport(typeWithoutGeneric(type));
+ }
+
+ private String typeWithoutGeneric(String type) {
+ int genericIndex = type.indexOf("<");
+ return genericIndex == -1 ? type : type.substring(0, genericIndex);
+ }
+
@Override
public GeneratorLanguage generatorLanguage() {
return GeneratorLanguage.TYPESCRIPT;
diff --git a/modules/openapi-generator/src/test/java/org/openapitools/codegen/typescript/SharedTypeScriptTest.java b/modules/openapi-generator/src/test/java/org/openapitools/codegen/typescript/SharedTypeScriptTest.java
index bce54e538147..cfc293b36621 100644
--- a/modules/openapi-generator/src/test/java/org/openapitools/codegen/typescript/SharedTypeScriptTest.java
+++ b/modules/openapi-generator/src/test/java/org/openapitools/codegen/typescript/SharedTypeScriptTest.java
@@ -2,10 +2,13 @@
import org.apache.commons.io.FileUtils;
import org.apache.commons.lang3.StringUtils;
+import org.openapitools.codegen.ClientOptInput;
import org.openapitools.codegen.DefaultGenerator;
import org.openapitools.codegen.Generator;
+import org.openapitools.codegen.TestUtils;
import org.openapitools.codegen.config.CodegenConfigurator;
import org.openapitools.codegen.languages.TypeScriptAxiosClientCodegen;
+import org.openapitools.codegen.languages.TypeScriptFetchClientCodegen;
import org.testng.Assert;
import org.testng.annotations.Test;
@@ -109,4 +112,76 @@ public void toModelImportMapTest() {
Assert.assertEquals(mapped, entry.getValue());
}
}
+
+ @Test(description = "Issue #21317")
+ public void givenTypeMappingContainsGenericAndMappedTypeIsUtilityTypeThenTypeIsNotImportedAndTypeAppearsCorrectly() throws Exception {
+ File output = Files.createTempDirectory("test").toFile().getCanonicalFile();
+ output.deleteOnExit();
+
+ File mainOutput = new File(output, "main");
+
+ Generator generator = new DefaultGenerator();
+ CodegenConfigurator configurator = new CodegenConfigurator()
+ .setInputSpec("src/test/resources/3_1/issue_21317.yaml")
+ .setGeneratorName("typescript-fetch")
+ .addTypeMapping("object", "Record")
+ .setOutputDir(mainOutput.getAbsolutePath());
+ ClientOptInput clientOptInput = configurator.toClientOptInput();
+ generator.opts(clientOptInput)
+ .generate();
+ String mainPath = mainOutput.getAbsolutePath();
+ File userModel = new File(mainPath, "/models/User.ts");
+
+ TestUtils.assertFileNotContains(userModel.toPath(), "Recordstringunknown");
+ TestUtils.assertFileContains(userModel.toPath(), "Record");
+ }
+
+ @Test(description = "Issue #21317")
+ public void givenTypeMappingContainsGenericAndMappedTypeIsUtilityAndWithoutRuntimeChecksTrueTypeThenTypeIsNotImportedAndTypeAppearsCorrectly() throws Exception {
+ File output = Files.createTempDirectory("test").toFile().getCanonicalFile();
+ output.deleteOnExit();
+
+ Generator generator = new DefaultGenerator();
+
+ CodegenConfigurator noRuntimeConfigurator = new CodegenConfigurator()
+ .setInputSpec("src/test/resources/3_1/issue_21317.yaml")
+ .setGeneratorName("typescript-fetch")
+ .addTypeMapping("object", "Record")
+ .addTypeMapping("UserSummary", "Pick")
+ .addAdditionalProperty(TypeScriptFetchClientCodegen.WITHOUT_RUNTIME_CHECKS, true)
+ .setOutputDir(output.getAbsolutePath());
+ ClientOptInput clientOptInput2 = noRuntimeConfigurator.toClientOptInput();
+ generator.opts(clientOptInput2)
+ .generate();
+ String noRuntimePath = output.getAbsolutePath();
+ File apiFile = new File(noRuntimePath, "/apis/DefaultApi.ts");
+ System.out.println(Files.readString(apiFile.toPath()));
+
+ TestUtils.assertFileContains(apiFile.toPath(), "Promise>");
+ TestUtils.assertFileNotContains(apiFile.toPath(), "Promise")
+ .addTypeMapping("object", "Record")
+ .setOutputDir(output.getAbsolutePath());
+ generator.opts(configurator.toClientOptInput())
+ .generate();
+
+ File axiosApiFile = new File(output, "/api.ts");
+
+ TestUtils.assertFileContains(axiosApiFile.toPath(), "AxiosPromise>");
+ TestUtils.assertFileNotContains(axiosApiFile.toPath(), "AxiosPromise");
+ }
+
}
diff --git a/modules/openapi-generator/src/test/resources/3_1/issue_21317.yaml b/modules/openapi-generator/src/test/resources/3_1/issue_21317.yaml
new file mode 100644
index 000000000000..eab17e0cd335
--- /dev/null
+++ b/modules/openapi-generator/src/test/resources/3_1/issue_21317.yaml
@@ -0,0 +1,60 @@
+# Significantly modified from the original
+openapi: 3.1.0
+info:
+ title: Sample API
+ description: Optional multiline or single-line description in [CommonMark](http://commonmark.org/help/) or HTML.
+ version: 1.0.0
+
+servers:
+ - url: http://api.example.com/v1
+ description: Optional server description, e.g. Main (production) server
+ - url: http://staging-api.example.com
+ description: Optional server description, e.g. Internal staging server for testing
+
+paths:
+ /users:
+ get:
+ summary: Returns a list of users.
+ description: Optional extended description in CommonMark or HTML.
+ responses:
+ "200": # status code
+ description: A JSON array of user names
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/User'
+ /users/summary:
+ get:
+ summary: Returns a list of users.
+ description: Optional extended description in CommonMark or HTML.
+ responses:
+ "200": # status code
+ description: A JSON array of user names
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/UserSummary'
+components:
+ schemas:
+ User:
+ type: object
+ properties:
+ id:
+ type: integer
+ format: int64
+ description: The user ID.
+ name:
+ type: string
+ description: The user name.
+ email:
+ type: string
+ format: email
+ description: The user email address.
+ metadata:
+ type: object
+ UserSummary:
+ type: object
+ properties:
+ name:
+ type: string
+ description: The user name.
\ No newline at end of file