oxc-project/oxc · warning · OxcDiagnostic

Don't use `Function` as a type

Error message

Don't use `Function` as a type

What it means

Warning from typescript/ban-types via function() (crates/oxc_linter/src/rules/typescript/ban_types.rs:29). It fires when 'Function' is used as a type: Function accepts any callable and its parameters/return are implicitly 'any', defeating type checking at the call boundary.

Source

Thrown at crates/oxc_linter/src/rules/typescript/ban_types.rs:29

};

fn type_diagnostic(banned_type: &str, suggested_type: &str, span: Span) -> OxcDiagnostic {
    OxcDiagnostic::warn(format!(
        "Do not use {banned_type:?} as a type. Use \"{suggested_type}\" instead"
    ))
    .with_help(format!("Replace {banned_type:?} with the lowercase primitive type \"{suggested_type}\"."))
    .with_note(format!("{banned_type} is a wrapper object type, while {suggested_type} is the primitive type. Using the primitive type is more idiomatic and avoids confusion between the object wrapper and the primitive value."))
    .with_label(span)
}

fn type_literal(span: Span) -> OxcDiagnostic {
    OxcDiagnostic::warn("Prefer explicitly define the object shape")
        .with_help("This type means \"any non-nullish value\", which is slightly better than 'unknown', but it's still a broad type")
        .with_label(span)
}

fn function(span: Span) -> OxcDiagnostic {
    OxcDiagnostic::warn("Don't use `Function` as a type")
        .with_help("The `Function` type accepts any function-like value")
        .with_label(span)
}

fn object(span: Span) -> OxcDiagnostic {
    OxcDiagnostic::warn("'The `Object` type actually means \"any non-nullish value\"")
        .with_help("Replace `Object` with a more specific type. If you need a generic object, use `Record<string, unknown>` or define an interface/type with explicit properties. If you need any value, use `unknown` instead.")
        .with_note("The `Object` type is confusing because it doesn't mean 'any object' - it means 'any non-nullish value', which includes primitives. This makes code harder to understand and can lead to unexpected behavior.")
        .with_label(span)
}

#[derive(Debug, Default, Clone)]
pub struct BanTypes;

declare_oxc_lint!(
    /// ### What it does
    ///
    /// This rule bans specific types and can suggest alternatives. Note that it does not ban the corresponding runtime objects from being used.

View on GitHub (pinned to e1e7af627c)

Solutions

  1. Replace with a concrete signature matching the expected shape, e.g. '() => void' or '(event: Event) => void'
  2. For truly arbitrary callables use '(...args: unknown[]) => unknown'
  3. Define a named call-signature interface when the same function shape repeats

Example fix

// before
const cb: Function = () => console.log('hi');

// after
const cb: () => void = () => console.log('hi');
Defensive patterns

Strategy: type-guard

Validate before calling

const FN = /:\s*Function\b/;
for (const line of source.split('\n')) {
  if (FN.test(line)) fail('untyped Function used as a type', line);
}

Type guard

function isCallableOf<S extends (...args: never[]) => unknown>(v: unknown): v is S {
  return typeof v === 'function';
}

Prevention

When it happens

Trigger: A type reference to the global Function name: 'const cb: Function = () => {}', 'register(handler: Function)', or 'new Map<string, Function>()' — hit wherever the rule resolves the identifier to the banned global.

Common situations: Callback-heavy APIs written before typed signatures were established; quick 'any function' placeholders in event registries or plugin systems; ported JavaScript with minimal typing.

Related errors


AI-assisted analysis of oxc-project/oxc@e1e7af627c (2026-08-20). Data as JSON: /api/errors/a8da86c4e6117b28. Report an issue: GitHub.