diff --git a/packages/jsii-rosetta/lib/jsii/jsii-types.ts b/packages/jsii-rosetta/lib/jsii/jsii-types.ts
index 079eeb7444..537b286446 100644
--- a/packages/jsii-rosetta/lib/jsii/jsii-types.ts
+++ b/packages/jsii-rosetta/lib/jsii/jsii-types.ts
@@ -25,8 +25,13 @@ export function determineJsiiType(typeChecker: ts.TypeChecker, type: ts.Type): J
   }
 
   const mapValuesType = mapElementType(type, typeChecker);
-  if (mapValuesType) {
-    return { kind: 'map', elementType: determineJsiiType(typeChecker, mapValuesType) };
+  if (mapValuesType.result === 'map') {
+    return {
+      kind: 'map',
+      elementType: mapValuesType.elementType
+        ? determineJsiiType(typeChecker, mapValuesType.elementType)
+        : { kind: 'builtIn', builtIn: 'any' },
+    };
   }
 
   // User-defined or aliased type
diff --git a/packages/jsii-rosetta/lib/languages/csharp.ts b/packages/jsii-rosetta/lib/languages/csharp.ts
index bcf6310466..6fcd648e44 100644
--- a/packages/jsii-rosetta/lib/languages/csharp.ts
+++ b/packages/jsii-rosetta/lib/languages/csharp.ts
@@ -409,7 +409,7 @@ export class CSharpVisitor extends DefaultVisitor<CSharpLanguageContext> {
       });
     }
     // Type information missing and from context we prefer a map
-    return this.keyValueObjectLiteralExpression(node, undefined, renderer);
+    return this.keyValueObjectLiteralExpression(node, renderer);
   }
 
   public knownStructObjectLiteralExpression(
@@ -424,15 +424,9 @@ export class CSharpVisitor extends DefaultVisitor<CSharpLanguageContext> {
     });
   }
 
-  public keyValueObjectLiteralExpression(
-    node: ts.ObjectLiteralExpression,
-    valueType: ts.Type | undefined,
-    renderer: CSharpRenderer,
-  ): OTree {
+  public keyValueObjectLiteralExpression(node: ts.ObjectLiteralExpression, renderer: CSharpRenderer): OTree {
     // Try to infer an element type from the elements
-    if (valueType === undefined) {
-      valueType = inferMapElementType(node.properties, renderer);
-    }
+    const valueType = inferMapElementType(node.properties, renderer.typeChecker);
 
     return new OTree(
       ['new Dictionary<string, ', this.renderType(node, valueType, false, 'object', renderer), '> { '],
diff --git a/packages/jsii-rosetta/lib/languages/default.ts b/packages/jsii-rosetta/lib/languages/default.ts
index 34a8e082be..c3b07a1f8d 100644
--- a/packages/jsii-rosetta/lib/languages/default.ts
+++ b/packages/jsii-rosetta/lib/languages/default.ts
@@ -5,7 +5,6 @@ import { OTree, NO_SYNTAX } from '../o-tree';
 import { AstRenderer, AstHandler, nimpl, CommentSyntax } from '../renderer';
 import { voidExpressionString } from '../typescript/ast-utils';
 import { ImportStatement } from '../typescript/imports';
-import { mapElementType } from '../typescript/types';
 
 import { TargetLanguage } from '.';
 
@@ -162,7 +161,7 @@ export abstract class DefaultVisitor<C> implements AstHandler<C> {
       // eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion
       return this.knownStructObjectLiteralExpression(node, type!, context);
     }
-    return this.keyValueObjectLiteralExpression(node, type && mapElementType(type, context.typeChecker), context);
+    return this.keyValueObjectLiteralExpression(node, context);
   }
 
   public unknownTypeObjectLiteralExpression(node: ts.ObjectLiteralExpression, context: AstRenderer<C>): OTree {
@@ -177,11 +176,7 @@ export abstract class DefaultVisitor<C> implements AstHandler<C> {
     return this.notImplemented(node, context);
   }
 
-  public keyValueObjectLiteralExpression(
-    node: ts.ObjectLiteralExpression,
-    _valueType: ts.Type | undefined,
-    context: AstRenderer<C>,
-  ): OTree {
+  public keyValueObjectLiteralExpression(node: ts.ObjectLiteralExpression, context: AstRenderer<C>): OTree {
     return this.notImplemented(node, context);
   }
 
diff --git a/packages/jsii-rosetta/lib/languages/java.ts b/packages/jsii-rosetta/lib/languages/java.ts
index 890e88131b..a4c2b8eb1f 100644
--- a/packages/jsii-rosetta/lib/languages/java.ts
+++ b/packages/jsii-rosetta/lib/languages/java.ts
@@ -452,14 +452,10 @@ export class JavaVisitor extends DefaultVisitor<JavaContext> {
   public unknownTypeObjectLiteralExpression(node: ts.ObjectLiteralExpression, renderer: JavaRenderer): OTree {
     return renderer.currentContext.inNewExprWithObjectLiteralAsLastArg
       ? this.renderObjectLiteralAsBuilder(node, renderer)
-      : this.keyValueObjectLiteralExpression(node, undefined, renderer);
+      : this.keyValueObjectLiteralExpression(node, renderer);
   }
 
-  public keyValueObjectLiteralExpression(
-    node: ts.ObjectLiteralExpression,
-    _valueType: ts.Type | undefined,
-    renderer: JavaRenderer,
-  ): OTree {
+  public keyValueObjectLiteralExpression(node: ts.ObjectLiteralExpression, renderer: JavaRenderer): OTree {
     return new OTree(['Map.of('], renderer.updateContext({ inKeyValueList: true }).convertAll(node.properties), {
       suffix: ')',
       separator: ', ',
diff --git a/packages/jsii-rosetta/lib/languages/python.ts b/packages/jsii-rosetta/lib/languages/python.ts
index f2603c913f..b514953bb9 100644
--- a/packages/jsii-rosetta/lib/languages/python.ts
+++ b/packages/jsii-rosetta/lib/languages/python.ts
@@ -346,11 +346,7 @@ export class PythonVisitor extends DefaultVisitor<PythonLanguageContext> {
     return this.renderObjectLiteralExpression(`${structType.symbol.name}(`, ')', true, node, context);
   }
 
-  public keyValueObjectLiteralExpression(
-    node: ts.ObjectLiteralExpression,
-    _valueType: ts.Type | undefined,
-    context: PythonVisitorContext,
-  ): OTree {
+  public keyValueObjectLiteralExpression(node: ts.ObjectLiteralExpression, context: PythonVisitorContext): OTree {
     return this.renderObjectLiteralExpression('{', '}', false, node, context);
   }
 
diff --git a/packages/jsii-rosetta/lib/typescript/types.ts b/packages/jsii-rosetta/lib/typescript/types.ts
index f28fa9cb9b..55d5b16ba7 100644
--- a/packages/jsii-rosetta/lib/typescript/types.ts
+++ b/packages/jsii-rosetta/lib/typescript/types.ts
@@ -1,7 +1,6 @@
 import * as ts from 'typescript';
 
 import { hasAllFlags, hasAnyFlag } from '../jsii/jsii-utils';
-import { AstRenderer } from '../renderer';
 
 /**
  * Return the first non-undefined type from a union
@@ -72,53 +71,55 @@ export function renderTypeFlags(type: ts.Type): string {
   return renderFlags(type.flags, ts.TypeFlags);
 }
 
+export type MapAnalysis = { result: 'nonMap' } | { result: 'map'; elementType: ts.Type | undefined };
+
 /**
  * If this is a map type, return the type mapped *to* (key must always be `string` anyway).
  */
-export function mapElementType(type: ts.Type, typeChecker: ts.TypeChecker): ts.Type | undefined {
-  if (type.flags & ts.TypeFlags.Object && type.symbol) {
+export function mapElementType(type: ts.Type, typeChecker: ts.TypeChecker): MapAnalysis {
+  if (hasAnyFlag(type.flags, ts.TypeFlags.Object) && type.symbol) {
     if (type.symbol.name === '__type') {
       // Declared map type: {[k: string]: A}
-      return type.getStringIndexType();
+      return { result: 'map', elementType: type.getStringIndexType() };
     }
 
     if (type.symbol.name === '__object') {
       // Derived map type from object literal: typeof({ k: "value" })
       // For every property, get the node that created it (PropertyAssignment), and get the type of the initializer of that node
       const initializerTypes = type.getProperties().map((p) => {
-        if (ts.isPropertyAssignment(p.valueDeclaration)) {
-          return typeOfExpression(typeChecker, p.valueDeclaration.initializer);
-        }
-        return undefined;
+        const expression = p.valueDeclaration;
+        return typeOfObjectLiteralProperty(typeChecker, expression);
       });
-      return typeIfSame([...initializerTypes, type.getStringIndexType()]);
+      return {
+        result: 'map',
+        elementType: typeIfSame([...initializerTypes, type.getStringIndexType()].filter(isDefined)),
+      };
     }
   }
 
-  return undefined;
+  return { result: 'nonMap' };
 }
 
 /**
  * Try to infer the map element type from the properties if they're all the same
  */
 export function inferMapElementType(
-  elements: ts.NodeArray<ts.ObjectLiteralElementLike>,
-  renderer: AstRenderer<any>,
+  elements: readonly ts.ObjectLiteralElementLike[],
+  typeChecker: ts.TypeChecker,
 ): ts.Type | undefined {
-  const nodes = elements.map(elementValueNode).filter(isDefined);
-  const types = nodes.map((x) => renderer.typeOfExpression(x));
+  const types = elements.map((e) => typeOfObjectLiteralProperty(typeChecker, e)).filter(isDefined);
 
   return types.every((t) => isSameType(types[0], t)) ? types[0] : undefined;
+}
 
-  function elementValueNode(el: ts.ObjectLiteralElementLike): ts.Expression | undefined {
-    if (ts.isPropertyAssignment(el)) {
-      return el.initializer;
-    }
-    if (ts.isShorthandPropertyAssignment(el)) {
-      return el.name;
-    }
-    return undefined;
+function typeOfObjectLiteralProperty(typeChecker: ts.TypeChecker, el: ts.Node): ts.Type | undefined {
+  if (ts.isPropertyAssignment(el)) {
+    return typeOfExpression(typeChecker, el.initializer);
   }
+  if (ts.isShorthandPropertyAssignment(el)) {
+    return typeOfExpression(typeChecker, el.name);
+  }
+  return undefined;
 }
 
 function isSameType(a: ts.Type, b: ts.Type) {
diff --git a/packages/jsii-rosetta/test/translations/statements/initialize_object_literal.cs b/packages/jsii-rosetta/test/translations/statements/initialize_object_literal.cs
new file mode 100644
index 0000000000..6f5bdfa6a2
--- /dev/null
+++ b/packages/jsii-rosetta/test/translations/statements/initialize_object_literal.cs
@@ -0,0 +1,5 @@
+IDictionary<string, object> expected = new Dictionary<string, object> {
+    { "Foo", "Bar" },
+    { "Baz", 5 },
+    { "Qux", new [] { "Waldo", "Fred" } }
+};
\ No newline at end of file
diff --git a/packages/jsii-rosetta/test/translations/statements/initialize_object_literal.java b/packages/jsii-rosetta/test/translations/statements/initialize_object_literal.java
new file mode 100644
index 0000000000..583983c561
--- /dev/null
+++ b/packages/jsii-rosetta/test/translations/statements/initialize_object_literal.java
@@ -0,0 +1,4 @@
+Map<String, Object> expected = Map.of(
+        "Foo", "Bar",
+        "Baz", 5,
+        "Qux", List.of("Waldo", "Fred"));
\ No newline at end of file
diff --git a/packages/jsii-rosetta/test/translations/statements/initialize_object_literal.py b/packages/jsii-rosetta/test/translations/statements/initialize_object_literal.py
new file mode 100644
index 0000000000..e0a2bd2974
--- /dev/null
+++ b/packages/jsii-rosetta/test/translations/statements/initialize_object_literal.py
@@ -0,0 +1,5 @@
+expected = {
+    "Foo": "Bar",
+    "Baz": 5,
+    "Qux": ["Waldo", "Fred"]
+}
\ No newline at end of file
diff --git a/packages/jsii-rosetta/test/translations/statements/initialize_object_literal.ts b/packages/jsii-rosetta/test/translations/statements/initialize_object_literal.ts
new file mode 100644
index 0000000000..a9da94d3d2
--- /dev/null
+++ b/packages/jsii-rosetta/test/translations/statements/initialize_object_literal.ts
@@ -0,0 +1,5 @@
+const expected = {
+  Foo: 'Bar',
+  Baz: 5,
+  Qux: [ 'Waldo', 'Fred' ],
+};
\ No newline at end of file