@studnicky/interfaces-compose-named-types
Requires valid contract interfaces to reference named schema-derived entity types for inline pure-data portions.
The rule examines inline object literals and mapped types inside retained contract interfaces. It reports a portion only when the shared classifier determines it is pure data. Inline callable, constructor, runtime, readonly, brand, or other contract objects are legitimate interface structure. Bare string, number, and boolean members do not need extraction.
Fixable: No · Options: No · Suggested severity: error
Rule boundary
The rule runs after interface declaration-shape classification:
interface-must-be-contractowns an interface that contains only pure data.- This rule skips that pure-data interface to avoid a second root diagnostic.
- This rule inspects a retained contract interface for inline pure-data portions.
- Each pure-data portion is extracted to a schema-derived entity and referenced through its named
Type.
The constraint declaration of a generic type parameter is outside this rule. A member that refers to that parameter is still checked through its resolved constraint, so a pure-data shape cannot be hidden behind T. The same resolution applies to indexed member access such as Source['value'].
✗ Incorrect
interface UserReaderInterface {
read(): {
id: string;
name: string;
};
}interface RegistryInterface {
readonly entries: {
[key: string]: {
id: string;
enabled: boolean;
};
};
}interface BigInterface {
a: { x: string; y: string };
b: string;
}
interface WrapperInterface {
run(): void;
value: BigInterface['a'];
}interface HandlerInterface<T extends { a: string; b: string } = never> {
run(): void;
handler: T;
}✓ Correct
interface ServiceInterface {
run(): void;
}interface FetchOptionsInterface {
(): void;
readonly 'headers'?: Record<string, string>;
}interface SchedulerInterface {
(): void;
readonly 'handle': ReturnType<typeof setTimeout>;
}interface DispatcherInterface {
handler: (() => void) | { a: 1 };
}Each pure-data portion is extracted to a schema-derived entity and referenced through its named Type.
Scoped exceptions
Source comments and per-member allow lists do not change classification. Disable the rule only for an explicitly scoped flat-config file set:
export default [
{
files: ['src/**/*.ts'],
rules: {
'@studnicky/interfaces-compose-named-types': 'error'
}
},
{
files: ['generated/**/*.ts'],
rules: {
'@studnicky/interfaces-compose-named-types': 'off'
}
}
];Related rules
interface-must-be-contractowns pure-data interface declarations.type-alias-invariantsverifies canonical alias provenance and declaration shape.all-types-are-entitiesowns canonical alias placement.no-mixed-callable-shapesowns a member whose type mixes a callable constituent with data — this rule skips that constituent rather than telling the consumer to extract it, since the underlying shape must split instead.