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' };
}