{"record":{"id":"629e66a17ae218dd","repo":"oxc-project/oxc","slug":"a-function-with-a-name-starting-with-an-uppercase","errorCode":null,"errorMessage":"A function with a name starting with an uppercase letter should only be used as a constructor.","messagePattern":"A function with a name starting with an uppercase letter should only be used as a constructor\\.","errorType":"validation","errorClass":"OxcDiagnostic","httpStatus":null,"severity":"warning","filePath":"crates/oxc_linter/src/rules/eslint/new_cap.rs","lineNumber":40,"sourceCode":"    let msg = if *cap == GetCapResult::Lower {\n        \"A constructor name should not start with a lowercase letter.\"\n    } else {\n        \"A function with a name starting with an uppercase letter should only be used as a constructor.\"\n    };\n\n    let label = if *cap == GetCapResult::Lower {\n        \"This should be uppercase\"\n    } else {\n        \"This should be called with `new`\"\n    };\n\n    let help = if *cap == GetCapResult::Lower {\n        \"Capitalize the first letter of the constructor name, or add it to the exceptions list if it should not be capitalized.\"\n    } else {\n        \"Use the new operator when calling this function, or add it to the exceptions list if it should not be called with new.\"\n    };\n\n    OxcDiagnostic::warn(msg).with_help(help).with_label(span.label(label))\n}\n\n#[derive(Debug, Default, Clone, Deserialize)]\npub struct NewCap(Box<NewCapConfig>);\n\n#[derive(Debug, Clone, Deserialize, JsonSchema)]\n#[serde(rename_all = \"camelCase\", default, deny_unknown_fields)]\npub struct NewCapConfig {\n    /// `true` to require that all constructor names start with an uppercase letter, e.g. `new Person()`.\n    new_is_cap: bool,\n    /// `true` to require that all functions with names starting with an uppercase letter to be called with `new`.\n    cap_is_new: bool,\n    /// Exceptions to ignore for constructor names starting with an uppercase letter.\n    new_is_cap_exceptions: Vec<CompactStr>,\n    /// A regex pattern to match exceptions for constructor names starting with an uppercase letter.\n    #[serde(default, deserialize_with = \"deserialize_regex_option\")]\n    new_is_cap_exception_pattern: Option<Regex>,\n    /// Exceptions to ignore for functions with names starting with an uppercase letter.","sourceCodeStart":22,"sourceCodeEnd":58,"githubUrl":"https://github.com/oxc-project/oxc/blob/1f902a69625cd14e6d8dc58feca94da099d2d251/crates/oxc_linter/src/rules/eslint/new_cap.rs#L22-L58","documentation":"The inverse branch of `new-cap`: with `capIsNew` enabled (default true), calling a function whose name starts with an uppercase letter without `new` produces this diagnostic ('A function with a name starting with an uppercase letter should only be used as a constructor.'). The label for this branch reads 'This should be called with `new`' and the help suggests using `new` or adding an exception (crates/oxc_linter/src/rules/eslint/new_cap.rs:31-43). It enforces the widespread convention that capitalized identifiers are constructors.","triggerScenarios":"`const p = Person();`, `Db.connect()` where `Db` is a capitalized function invoked as a normal call, `SomeLibrary.method()` with `properties: true` — any call expression whose callee begins with a capital letter and the target is a function, unless listed in `capIsNewExceptions` or matched by `capIsNewExceptionPattern` (both default empty).","commonSituations":"Libraries whose capitalized exports are plain factory functions (e.g. older jQuery-era APIs, `fetch`-wrapper libraries named `Client`); namespaced singletons like `Utils.method()`; refactoring a class into a factory and forgetting to lowercase the name; enabling `new-cap` after adding such a dependency.","solutions":["Add `new` if the target genuinely is a constructor: `const p = new Person();`.","If the capitalized identifier is a factory or namespace, add it to `capIsNewExceptions` or set `capIsNewExceptionPattern` (e.g. `\"^[A-Z][a-z]+\\\\.$\"` for namespaces) in the rule configuration.","Rename the factory to lowercase (`Client()` → `createClient()`) so the convention matches the usage."],"exampleFix":"// before\nconst client = ApiClient(base_url);\n\n// after\nconst client = new ApiClient(base_url);\n// or, if it is a factory: const client = createApiClient(base_url);","handlingStrategy":"validation","validationCode":"// CI: oxlint --rule new-cap src/\n// Before calling a capitalized import, check whether it is a class/constructor:\n// .oxlintrc.json -> \"capIsNewExceptions\": [\"Client\", \"Utils\"] or exceptionPattern for namespaces.","typeGuard":"// TypeScript narrowing by construct-signature presence:\ntype Constructor<T> = new (...args: any[]) => T;\nfunction isConstructor<T>(value: unknown): value is Constructor<T> {\n  return typeof value === 'function' && /^([A-Z])/.test(value.name);\n}","tryCatchPattern":null,"preventionTips":["Uppercase names are constructor-shaped by convention — reserve capitals for constructible types and use camelCase factories otherwise.","When introducing a factory, name it createX/makeX so it is never mistaken for a constructor.","Namespace objects (Utils.method()) should be listed via capIsNewExceptionPattern instead of disabling the whole rule."],"tags":["eslint","oxlint","style","naming","constructor","new-cap"],"backgroundTag":"constructor-naming-convention","analyzedSha":"1f902a69625cd14e6d8dc58feca94da099d2d251","analyzedAt":"2026-08-20T07:01:07.079Z","contentChangedAt":"2026-08-20T07:01:07.079Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}