UNPKG

eslint-plugin-fsecond

Version:
245 lines (179 loc) • 6.89 kB
# fsecond/no-inline-interfaces šŸ“ Disallow inline object type literals in variable and function annotations; extract to a named interface or type alias. šŸ’¼ This rule is enabled in the following configs: āœ… `recommended`, ā˜‘ļø `recommendedTypeChecked`. šŸ”§ This rule is automatically fixable by the [`--fix` CLI option](https://eslint.org/docs/latest/user-guide/command-line-interface#--fix). <!-- end auto-generated rule header --> ## Description This rule enforces extracting inline object type literals into named interfaces or type aliases, rather than defining them inline in variable declarations, function parameters, or return types. This rule flags inline object type literals (`{ prop: type }`) when used in: - Variable type annotations - Function parameter type annotations (including destructured parameters) - Function return type annotations (only when `checkReturnTypes: true`) The rule will flag object literals even when they appear within: - Union types (e.g., `{ a: string } | null`) - Intersection types (e.g., `A & { b: number }`) - Array types using bracket syntax (e.g., `{ a: string }[]`) - Tuple types (e.g., `[{ a: string }, number]`) ### What the rule always ignores **Classes:** The rule completely ignores anything inside classes, including class properties, method parameters, and method return types. This allows for flexibility in class-based code where inline types may be more appropriate. ## Rationale Extracting object types into named interfaces or type aliases: - Improves code readability and maintainability - Encourages type reusability across the codebase - Makes complex types easier to understand and document - Facilitates refactoring and type updates ## Options <!-- begin auto-generated rule options list --> | Name | Description | Type | Default | | :------------------ | :----------------------------------------------------------------------------------- | :------ | :------ | | `checkGenericTypes` | Check inline object types within generic type arguments (e.g., Array<{ a: string }>) | Boolean | `false` | | `checkReturnTypes` | Check inline object types in function return type annotations | Boolean | `false` | <!-- end auto-generated rule options list --> This rule accepts an options object with the following properties: ```typescript { checkGenericTypes?: boolean; // default: false checkReturnTypes?: boolean; // default: false } ``` ### `checkGenericTypes` (default: `false`) When `false` (default), the rule ignores inline object types within generic type arguments of type references (e.g., `Readonly<{ a: string }>`, `Promise<{ data: number }>`, `Array<{ a: string }>`). When `true`, the rule will flag inline object types even inside generic type arguments. ### `checkReturnTypes` (default: `false`) When `false` (default), the rule does NOT check function return type annotations. When `true`, the rule will flag inline object types in function return types. ## Examples ### āŒ Invalid ```typescript // Variable with inline object type const myVariable: { prop1: string; prop2: number } = {} as any; // Arrow function with inline object type on destructured params export const MyReactComponent = ({ prop1, prop2, }: { prop1: string; prop2: number; }) => {}; // Arrow function with inline object type on props param export const MyReactComponent = (props: { prop1: string; prop2: number }) => {}; // Function declaration with inline object type function MyReactComponent({ prop1, prop2 }: { prop1: string; prop2: number }) {} // Union with inline object type const data: { id: number } | null = null; // Intersection with inline object types const combined: { a: string } & { b: number } = {} as any; ``` **With `checkReturnTypes: true`:** ```typescript // Function with inline return type function getData(): { name: string; age: number } { return { name: "John", age: 30 }; } // Arrow function with inline return type const getUser = (): { id: string; name: string } => ({ id: "", name: "" }); ``` **With `checkGenericTypes: true`:** ```typescript // Generic type with inline object const items: Array<{ id: string }> = []; // Readonly with inline object const config: Readonly<{ debug: boolean }> = { debug: true }; // Promise with inline object const data: Promise<{ result: number }> = Promise.resolve({ result: 42 }); ``` ### āœ… Valid ```typescript // Using interface interface MyInterface { prop1: string; prop2: number; } const myVariable: MyInterface = {} as any; export const MyReactComponent = ({ prop1, prop2 }: MyInterface) => {}; export const MyReactComponent2 = (props: MyInterface) => {}; function MyFunction(props: MyInterface) {} // Using type alias type MyType = { prop1: string; prop2: number; }; const myVariable: MyType = {} as any; export const MyComponent = (props: MyType) => {}; // Return type with named type type ReturnType = { name: string; age: number }; function getData(): ReturnType { return { name: "John", age: 30 }; } // Union with named types interface Data { id: number; } const data: Data | null = null; // Primitives and other types const name: string = ""; const count: number = 0; const items: string[] = []; // Generic type arguments are ignored const readonly: Readonly<{ a: string }> = { a: "" }; const promise: Promise<{ data: number }> = Promise.resolve({ data: 1 }); // Classes are completely ignored class User { // Inline types in class properties are allowed data: { name: string; age: number }; // Inline types in class methods are allowed process(config: { debug: boolean; verbose: boolean }) {} getData(): { id: string; value: number } { return { id: "", value: 0 }; } } ``` ## Configuration Examples ### Default Configuration (Recommended) ```javascript // eslint.config.js export default [ { rules: { "fsecond/no-inline-interfaces": "error", }, }, ]; ``` This will check variables and function parameters, but NOT return types or generic type arguments. ### Strict Configuration ```javascript // eslint.config.js export default [ { rules: { "fsecond/no-inline-interfaces": [ "error", { checkReturnTypes: true, checkGenericTypes: true, }, ], }, }, ]; ``` This will check all inline object types including return types and those inside generics. ### Check Only Return Types ```javascript // eslint.config.js export default [ { rules: { "fsecond/no-inline-interfaces": [ "error", { checkReturnTypes: true, }, ], }, }, ]; ``` ## When Not To Use It If your codebase prefers inline type definitions for simple, one-off types that are only used in a single location, you may want to disable this rule.