diff --git a/CHANGELOG.md b/CHANGELOG.md
index fd9ae1f14e..e44fc669e2 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -15,6 +15,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Fixed a bug where scalar error mappings would be generated even though it's not supported by the http request adapter. [#4018](https://github.com/microsoft/kiota/issues/4018)
- Switched to proxy generation for TypeScript, leading to about ~44% bundle sizes reduction. [#3642](https://github.com/microsoft/kiota/issues/3642)
+- Fixed a bug where TypeScript models factory methods would be missing return types.
## [1.10.1] - 2024-01-12
diff --git a/src/Kiota.Builder/CodeDOM/CodeParameter.cs b/src/Kiota.Builder/CodeDOM/CodeParameter.cs
index 8499fa43a4..c283b9221a 100644
--- a/src/Kiota.Builder/CodeDOM/CodeParameter.cs
+++ b/src/Kiota.Builder/CodeDOM/CodeParameter.cs
@@ -52,6 +52,10 @@ public enum CodeParameterKind
/// The content type of the request body when it couldn't be inferred from the description.
///
RequestBodyContentType,
+ ///
+ /// When the deserialization method is replaced as a function, this is the parameter representing instance we're deserializing into.
+ ///
+ DeserializationTarget,
}
public class CodeParameter : CodeTerminalWithKind, ICloneable, IDocumentedElement, IDeprecableElement
diff --git a/src/Kiota.Builder/Refiners/TypeScriptRefiner.cs b/src/Kiota.Builder/Refiners/TypeScriptRefiner.cs
index c7ac33287d..43fdb97c1a 100644
--- a/src/Kiota.Builder/Refiners/TypeScriptRefiner.cs
+++ b/src/Kiota.Builder/Refiners/TypeScriptRefiner.cs
@@ -736,7 +736,8 @@ private static void AddInterfaceParamToSerializer(CodeInterface modelInterface,
{
Name = ReturnFinalInterfaceName(modelInterface.Name), // remove the interface suffix
DefaultValue = "{}",
- Type = new CodeType { Name = ReturnFinalInterfaceName(modelInterface.Name), TypeDefinition = modelInterface }
+ Type = new CodeType { Name = ReturnFinalInterfaceName(modelInterface.Name), TypeDefinition = modelInterface },
+ Kind = CodeParameterKind.DeserializationTarget,
});
if (modelInterface.Parent is not null)
diff --git a/src/Kiota.Builder/Writers/TypeScript/CodeFunctionWriter.cs b/src/Kiota.Builder/Writers/TypeScript/CodeFunctionWriter.cs
index aa8947f083..6f302d522c 100644
--- a/src/Kiota.Builder/Writers/TypeScript/CodeFunctionWriter.cs
+++ b/src/Kiota.Builder/Writers/TypeScript/CodeFunctionWriter.cs
@@ -26,7 +26,9 @@ public override void WriteCodeElement(CodeFunction codeElement, LanguageWriter w
var codeMethod = codeElement.OriginalLocalMethod;
- var returnType = codeMethod.Kind != CodeMethodKind.Factory ? conventions.GetTypeString(codeMethod.ReturnType, codeElement) : string.Empty;
+ var returnType = codeMethod.Kind is CodeMethodKind.Factory ?
+ "((instance?: Parsable) => Record void>)" :
+ conventions.GetTypeString(codeMethod.ReturnType, codeElement);
var isVoid = "void".EqualsIgnoreCase(returnType);
CodeMethodWriter.WriteMethodDocumentationInternal(codeElement.OriginalLocalMethod, writer, isVoid, conventions);
CodeMethodWriter.WriteMethodPrototypeInternal(codeElement.OriginalLocalMethod, writer, returnType, isVoid, conventions, true);
diff --git a/src/Kiota.Builder/Writers/TypeScript/TypeScriptConventionService.cs b/src/Kiota.Builder/Writers/TypeScript/TypeScriptConventionService.cs
index 886ee7b49f..0c0901e5f4 100644
--- a/src/Kiota.Builder/Writers/TypeScript/TypeScriptConventionService.cs
+++ b/src/Kiota.Builder/Writers/TypeScript/TypeScriptConventionService.cs
@@ -56,8 +56,18 @@ public override string GetParameterSignature(CodeParameter parameter, CodeElemen
{
ArgumentNullException.ThrowIfNull(parameter);
var paramType = GetTypeString(parameter.Type, targetElement);
- var defaultValueSuffix = string.IsNullOrEmpty(parameter.DefaultValue) ? string.Empty : $" = {parameter.DefaultValue} as {paramType}";
- return $"{parameter.Name.ToFirstCharacterLowerCase()}{(parameter.Optional && parameter.Type.IsNullable ? "?" : string.Empty)}: {paramType}{(parameter.Type.IsNullable ? " | undefined" : string.Empty)}{defaultValueSuffix}";
+ var defaultValueSuffix = (string.IsNullOrEmpty(parameter.DefaultValue), parameter.Kind) switch
+ {
+ (false, CodeParameterKind.DeserializationTarget) => $" = {parameter.DefaultValue}",
+ (false, _) => $" = {parameter.DefaultValue} as {paramType}",
+ (true, _) => string.Empty,
+ };
+ var (partialPrefix, partialSuffix) = parameter.Kind switch
+ {
+ CodeParameterKind.DeserializationTarget => ("Partial<", ">"),
+ _ => (string.Empty, string.Empty),
+ };
+ return $"{parameter.Name.ToFirstCharacterLowerCase()}{(parameter.Optional && parameter.Type.IsNullable ? "?" : string.Empty)}: {partialPrefix}{paramType}{partialSuffix}{(parameter.Type.IsNullable ? " | undefined" : string.Empty)}{defaultValueSuffix}";
}
public override string GetTypeString(CodeTypeBase code, CodeElement targetElement, bool includeCollectionInformation = true, LanguageWriter? writer = null)
{