Skip to content

Composite Rules

Composite rules enforce best practices in Composite() factory definitions. They ensure composites stay clean, consistent, and use lexicon types wherever possible.


Object literals and arrays-of-objects inside a Composite factory that don’t reference props or sibling members are extractable constants. Move them to a separate file (e.g. defaults.ts) and import directly.

SeverityWarning
CategoryStyle
// ❌ Triggers EVL009
const LambdaApi = Composite<Props>((props) => {
const role = new _.Role({
assumeRolePolicyDocument: {
Version: "2012-10-17",
Statement: [{ Effect: "Allow", Principal: { Service: "lambda.amazonaws.com" }, Action: "sts:AssumeRole" }],
},
});
return { role };
}, "LambdaApi");
// ✅ Fixed — extract to defaults.ts, import directly
const LambdaApi = Composite<Props>((props) => {
const role = new Role({
assumeRolePolicyDocument: lambdaTrustPolicy,
});
return { role };
}, "LambdaApi");

Simple string, number, and boolean literals are allowed inline — only object literals and arrays containing objects are flagged.


Composite factories should only compose resources from props, not transform data. Array methods like .map(), .filter(), .reduce(), and .flatMap() should be called before passing props to the composite.

SeverityWarning
CategoryStyle
// ❌ Triggers EVL010
const LambdaApi = Composite<Props>((props) => {
const role = new _.Role({
policies: props.policyStatements.map(s =>
new _.Role_Policy({ policyDocument: s })
),
});
return { role };
}, "LambdaApi");
// ✅ Fixed — caller constructs Role_Policy[] before passing
const LambdaApi = Composite<Props>((props) => {
const role = new _.Role({
policies: props.policies,
});
return { role };
}, "LambdaApi");

COR017: Composite Name Must Match Variable

Section titled “COR017: Composite Name Must Match Variable”

The second argument to Composite() must be a string literal that matches the const variable name. This name is used in resource expansion (e.g. healthApiRole, healthApiFunc) and error messages.

SeverityError
CategoryCorrectness
Auto-fixYes
// ❌ Triggers COR017 — name mismatch
const LambdaApi = Composite<Props>((props) => {
return { role: new _.Role({}) };
}, "MyFunction");
// ❌ Triggers COR017 — missing name
const LambdaApi = Composite<Props>((props) => {
return { role: new _.Role({}) };
});
// ✅ Fixed
const LambdaApi = Composite<Props>((props) => {
return { role: new _.Role({}) };
}, "LambdaApi");

Composite prop interfaces should use lexicon property types instead of locally-declared interfaces. If the lexicon already provides a matching type (e.g. Role_Policy), use InstanceType<typeof _.Role_Policy> instead of defining a custom interface.

SeverityInfo
CategoryStyle
// ❌ Triggers COR018 — local interface duplicates lexicon type
interface PolicyStatement {
effect: string;
action: string[];
resource: string[];
}
interface LambdaApiProps {
policies?: PolicyStatement[];
}
const LambdaApi = Composite<LambdaApiProps>((props) => {
// ...
}, "LambdaApi");
// ✅ Fixed — use lexicon property type
interface LambdaApiProps {
policies?: InstanceType<typeof _.Role_Policy>[];
}
const LambdaApi = Composite<LambdaApiProps>((props) => {
// ...
}, "LambdaApi");