diff --git a/src/NJsonSchema.CodeGeneration.TypeScript.Tests/InheritanceTests.cs b/src/NJsonSchema.CodeGeneration.TypeScript.Tests/InheritanceTests.cs index 1b8b355b8..e95145535 100644 --- a/src/NJsonSchema.CodeGeneration.TypeScript.Tests/InheritanceTests.cs +++ b/src/NJsonSchema.CodeGeneration.TypeScript.Tests/InheritanceTests.cs @@ -119,6 +119,28 @@ public async Task When_class_with_discriminator_has_base_class_then_csharp_is_ge Assert.Contains("if (data[\"kind\"] === \"MyException\") {", code); } + [Fact] + public async Task When_interfaces_are_generated_with_inheritance_then_type_check_methods_are_generated() + { + //// Arrange + var schema = JsonSchema.FromType(); + var data = schema.ToJson(); + + var generator = new TypeScriptGenerator(schema, new TypeScriptGeneratorSettings + { + TypeScriptVersion = 2.0m, + TypeStyle = TypeScriptTypeStyle.Interface, + GenerateTypeCheckFunctions = true + }); + + //// Act + var code = generator.GenerateFile(); + + //// Assert + Assert.Contains("export function isExceptionBase(object: any): object is ExceptionBase {", code); + Assert.Contains("function isMyException(object: any): object is MyException {", code); + } + [Fact] public async Task When_discriminator_does_not_match_typename_then_TypeScript_is_correct() { @@ -322,7 +344,8 @@ public async Task When_schema_with_inheritance_and_references_is_generated_then_ [Fact] - public async Task When_class_has_baseclass_and_extension_code_baseclass_is_preserved() { + public async Task When_class_has_baseclass_and_extension_code_baseclass_is_preserved() + { //// Arrange string extensionCode = @" import * as generated from ""./generated""; @@ -333,7 +356,8 @@ export class ExceptionBase extends generated.ExceptionBase { "; var schema = JsonSchema.FromType(); - var generator = new TypeScriptGenerator(schema, new TypeScriptGeneratorSettings { + var generator = new TypeScriptGenerator(schema, new TypeScriptGeneratorSettings + { ExtensionCode = extensionCode, ExtendedClasses = new[] { "ExceptionBase" }, }); diff --git a/src/NJsonSchema.CodeGeneration.TypeScript/Models/ClassTemplateModel.cs b/src/NJsonSchema.CodeGeneration.TypeScript/Models/ClassTemplateModel.cs index e87a5d757..a82264f1f 100644 --- a/src/NJsonSchema.CodeGeneration.TypeScript/Models/ClassTemplateModel.cs +++ b/src/NJsonSchema.CodeGeneration.TypeScript/Models/ClassTemplateModel.cs @@ -149,6 +149,9 @@ public string IndexerPropertyValueType /// Gets a value indicating whether the export keyword should be added to all classes. public bool ExportTypes => _settings.ExportTypes; + /// Gets a value indicating whether to generate type check functions. + public bool GenerateTypeCheckFunctions => _settings.GenerateTypeCheckFunctions; + /// Gets the inherited schema. private JsonSchema InheritedSchema => _schema.InheritedSchema?.ActualSchema; } diff --git a/src/NJsonSchema.CodeGeneration.TypeScript/Templates/Interface.liquid b/src/NJsonSchema.CodeGeneration.TypeScript/Templates/Interface.liquid index 1396d01ed..554f4c559 100644 --- a/src/NJsonSchema.CodeGeneration.TypeScript/Templates/Interface.liquid +++ b/src/NJsonSchema.CodeGeneration.TypeScript/Templates/Interface.liquid @@ -12,4 +12,10 @@ [key: string]: {{ IndexerPropertyValueType }}; {%- endif -%} -} \ No newline at end of file +} +{%- if GenerateTypeCheckFunctions and HasInheritance -%} + +{% if ExportTypes %}export {% endif %}function is{{ ClassName }}(object: any): object is {{ ClassName }} { + return object && object['{{ BaseDiscriminator }}'] === '{{ DiscriminatorName }}'; +} +{%- endif -%} \ No newline at end of file diff --git a/src/NJsonSchema.CodeGeneration.TypeScript/TypeScriptGeneratorSettings.cs b/src/NJsonSchema.CodeGeneration.TypeScript/TypeScriptGeneratorSettings.cs index 5727ec58d..f92bbfa14 100644 --- a/src/NJsonSchema.CodeGeneration.TypeScript/TypeScriptGeneratorSettings.cs +++ b/src/NJsonSchema.CodeGeneration.TypeScript/TypeScriptGeneratorSettings.cs @@ -43,6 +43,7 @@ public TypeScriptGeneratorSettings() ExtendedClasses = Array.Empty(); InlineNamedDictionaries = false; + GenerateTypeCheckFunctions = false; } /// Gets or sets the target TypeScript version (default: 2.7). @@ -108,6 +109,9 @@ public TypeScriptGeneratorSettings() /// Gets or sets a value indicating whether named/referenced dictionaries should be inlined or generated as class with an indexer. public bool InlineNamedDictionaries { get; set; } + /// Gets a value indicating whether to generate type check functions (for type style interface only, default: false). + public bool GenerateTypeCheckFunctions { get; set; } + internal ITemplate CreateTemplate(string typeName, object model) { if (ClassTypes != null && ClassTypes.Contains(typeName))