export function analyzeObjectLiteral()

in src/jsii/jsii-types.ts [90:122]


export function analyzeObjectLiteral(
  typeChecker: ts.TypeChecker,
  node: ts.ObjectLiteralExpression,
): ObjectLiteralAnalysis {
  const type = inferredTypeOfExpression(typeChecker, node);
  if (!type) {
    return { kind: 'unknown' };
  }

  const call = findEnclosingCallExpression(node);
  const isDeclaredCall = !!(call && typeChecker.getResolvedSignature(call)?.declaration);

  if (hasAnyFlag(type.flags, ts.TypeFlags.Any)) {
    // The type checker by itself won't tell us the difference between an `any` that
    // was literally declared as a type in the code, vs an `any` it assumes because it
    // can't find a function's type declaration.
    //
    // Search for the function's declaration and only if we can't find it,
    // the type is actually unknown (otherwise it's a literal 'any').
    return isDeclaredCall ? { kind: 'map' } : { kind: 'unknown' };
  }

  // If the type is a union between a struct and something else, return the first possible struct
  const structCandidates = type.isUnion() ? type.types : [type];
  for (const candidate of structCandidates) {
    const structType = analyzeStructType(typeChecker, candidate);
    if (structType) {
      return structType;
    }
  }

  return { kind: 'map' };
}