From 89d9488507c293c14223a43c505d841ab428c899 Mon Sep 17 00:00:00 2001 From: "Per Christian B. Viken" Date: Sat, 11 Apr 2026 09:36:34 +0200 Subject: [PATCH 1/2] feat(lib): Add default maps for unsigned numbers Fixes #180 --- CHANGELOG.md | 1 + .../TypeScript/TypeScriptConverterTests.cs | 60 ++++++++++++++++--- TypeContractor/TypeContractorConfiguration.cs | 3 + 3 files changed, 55 insertions(+), 9 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 567d445..bfdda50 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Added - Simplified response for generated API clients using the React template (#203) +- Add default maps for unsigned numbers (#180) ### Fixed diff --git a/TypeContractor.Tests/TypeScript/TypeScriptConverterTests.cs b/TypeContractor.Tests/TypeScript/TypeScriptConverterTests.cs index 2c980bb..12221ab 100644 --- a/TypeContractor.Tests/TypeScript/TypeScriptConverterTests.cs +++ b/TypeContractor.Tests/TypeScript/TypeScriptConverterTests.cs @@ -36,7 +36,7 @@ public void Can_Convert_Simple_Types() result.FullName.Should().Be("TypeContractor.Tests.TypeScript.TypeScriptConverterTests+SimpleTypes"); result.IsEnum.Should().BeFalse(); result.EnumMembers.Should().BeNull(); - result.Properties.Should().HaveCount(6); + result.Properties.Should().HaveCount(9); } [Theory] @@ -46,6 +46,9 @@ public void Can_Convert_Simple_Types() [InlineData(3)] [InlineData(4)] [InlineData(5)] + [InlineData(6)] + [InlineData(7)] + [InlineData(8)] public void Converted_Simple_Properties_Looks_As_Expected(int propertyIndex) { var result = Sut.Convert(typeof(SimpleTypes)); @@ -56,7 +59,7 @@ public void Converted_Simple_Properties_Looks_As_Expected(int propertyIndex) { case 0: prop.SourceName.Should().Be("StringProperty"); - prop.SourceType.Should().Be(typeof(string)); + prop.SourceType.Should().Be(); prop.InnerSourceType.Should().BeNull(); prop.DestinationName.Should().Be("stringProperty"); prop.DestinationType.Should().Be("string"); @@ -67,7 +70,7 @@ public void Converted_Simple_Properties_Looks_As_Expected(int propertyIndex) case 1: prop.SourceName.Should().Be("NumberProperty"); - prop.SourceType.Should().Be(typeof(int?)); + prop.SourceType.Should().Be(); prop.InnerSourceType.Should().BeNull(); prop.DestinationName.Should().Be("numberProperty"); prop.DestinationType.Should().Be("number"); @@ -78,8 +81,8 @@ public void Converted_Simple_Properties_Looks_As_Expected(int propertyIndex) case 2: prop.SourceName.Should().Be("NumbersProperty"); - prop.SourceType.Should().Be(typeof(IEnumerable)); - prop.InnerSourceType.Should().Be(typeof(int)); + prop.SourceType.Should().Be>(); + prop.InnerSourceType.Should().Be(); prop.DestinationName.Should().Be("numbersProperty"); prop.DestinationType.Should().Be("number"); prop.IsBuiltin.Should().BeTrue(); @@ -89,7 +92,7 @@ public void Converted_Simple_Properties_Looks_As_Expected(int propertyIndex) case 3: prop.SourceName.Should().Be("DoubleTime"); - prop.SourceType.Should().Be(typeof(double)); + prop.SourceType.Should().Be(); prop.InnerSourceType.Should().BeNull(); prop.DestinationName.Should().Be("doubleTime"); prop.DestinationType.Should().Be("number"); @@ -100,7 +103,7 @@ public void Converted_Simple_Properties_Looks_As_Expected(int propertyIndex) case 4: prop.SourceName.Should().Be("TimeyWimeySpan"); - prop.SourceType.Should().Be(typeof(TimeSpan)); + prop.SourceType.Should().Be(); prop.InnerSourceType.Should().BeNull(); prop.DestinationName.Should().Be("timeyWimeySpan"); prop.DestinationType.Should().Be("string"); @@ -111,7 +114,7 @@ public void Converted_Simple_Properties_Looks_As_Expected(int propertyIndex) case 5: prop.SourceName.Should().Be("SomeObject"); - prop.SourceType.Should().Be(typeof(object)); + prop.SourceType.Should().Be(); prop.InnerSourceType.Should().BeNull(); prop.DestinationName.Should().Be("someObject"); prop.DestinationType.Should().Be("any"); @@ -119,6 +122,39 @@ public void Converted_Simple_Properties_Looks_As_Expected(int propertyIndex) prop.IsArray.Should().BeFalse(); prop.IsNullable.Should().BeFalse(); break; + + case 6: + prop.SourceName.Should().Be("UnsignedNumber"); + prop.SourceType.Should().Be(); + prop.InnerSourceType.Should().BeNull(); + prop.DestinationName.Should().Be("unsignedNumber"); + prop.DestinationType.Should().Be("number"); + prop.IsBuiltin.Should().BeTrue(); + prop.IsArray.Should().BeFalse(); + prop.IsNullable.Should().BeFalse(); + break; + + case 7: + prop.SourceName.Should().Be("UnsignedButLargeNumber"); + prop.SourceType.Should().Be(); + prop.InnerSourceType.Should().BeNull(); + prop.DestinationName.Should().Be("unsignedButLargeNumber"); + prop.DestinationType.Should().Be("number"); + prop.IsBuiltin.Should().BeTrue(); + prop.IsArray.Should().BeFalse(); + prop.IsNullable.Should().BeFalse(); + break; + + case 8: + prop.SourceName.Should().Be("UnsignedShorty"); + prop.SourceType.Should().Be(); + prop.InnerSourceType.Should().BeNull(); + prop.DestinationName.Should().Be("unsignedShorty"); + prop.DestinationType.Should().Be("number"); + prop.IsBuiltin.Should().BeTrue(); + prop.IsArray.Should().BeFalse(); + prop.IsNullable.Should().BeFalse(); + break; } } @@ -138,7 +174,7 @@ public void Finds_Properties_From_Multiple_Base_Classes() var result = Sut.Convert(typeof(NestedInheritanceTest)); result.Properties.Should().NotBeNull(); - result.Properties.Should().HaveCount(8); + result.Properties.Should().HaveCount(11); result.Properties.Should() .Contain(x => x.SourceName == "StringProperty") .And.Contain(x => x.SourceName == "NumberProperty") @@ -146,6 +182,9 @@ public void Finds_Properties_From_Multiple_Base_Classes() .And.Contain(x => x.SourceName == "DoubleTime") .And.Contain(x => x.SourceName == "TimeyWimeySpan") .And.Contain(x => x.SourceName == "SomeObject") + .And.Contain(x => x.SourceName == "UnsignedNumber") + .And.Contain(x => x.SourceName == "UnsignedButLargeNumber") + .And.Contain(x => x.SourceName == "UnsignedShorty") .And.Contain(x => x.SourceName == "InheritedProperty") .And.Contain(x => x.SourceName == "FinalProperty"); } @@ -390,6 +429,9 @@ private class SimpleTypes public double DoubleTime { get; set; } public TimeSpan TimeyWimeySpan { get; set; } public object SomeObject { get; set; } + public uint UnsignedNumber { get; set; } + public ulong UnsignedButLargeNumber { get; set; } + public ushort UnsignedShorty { get; set; } } private class TypeVisibility diff --git a/TypeContractor/TypeContractorConfiguration.cs b/TypeContractor/TypeContractorConfiguration.cs index 69027ba..8e2b4e6 100644 --- a/TypeContractor/TypeContractorConfiguration.cs +++ b/TypeContractor/TypeContractorConfiguration.cs @@ -77,8 +77,11 @@ public TypeContractorConfiguration AddDefaultTypeMaps() AddCustomMap(typeof(bool), DestinationTypes.Boolean); AddCustomMap(typeof(byte), DestinationTypes.Number); AddCustomMap(typeof(short), DestinationTypes.Number); + AddCustomMap(typeof(ushort), DestinationTypes.Number); AddCustomMap(typeof(int), DestinationTypes.Number); + AddCustomMap(typeof(uint), DestinationTypes.Number); AddCustomMap(typeof(long), DestinationTypes.Number); + AddCustomMap(typeof(ulong), DestinationTypes.Number); AddCustomMap(typeof(decimal), DestinationTypes.Number); AddCustomMap(typeof(float), DestinationTypes.Number); AddCustomMap(typeof(double), DestinationTypes.Number); From afb26ec4d33e608138ac832f5deeb0f6d18191d4 Mon Sep 17 00:00:00 2001 From: "Per Christian B. Viken" Date: Sat, 11 Apr 2026 09:39:27 +0200 Subject: [PATCH 2/2] chore(github): Fix solution name in workflow --- .github/workflows/release.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 7d15a33..cf1d81a 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -17,7 +17,7 @@ jobs: id-token: write env: - SOLUTION: "TypeContractor.sln" + SOLUTION: "TypeContractor.slnx" DOTNET_CLI_TELEMETRY_OPTOUT: true runs-on: ubuntu-latest