Skip to content

TS types allow bivariant function parameters #4233

Closed
@twavv

Description

@twavv

Ignoring the template because it's not a runtime bug.

This is currently not an error in TypeScript:

// in Sentry (simplified)
interface Options {
  beforeSend?(event: Event, hint?: Hint): Event | null;
}

// in my code
  const opts: Sentry.Options = {
    beforeSend: (event, hint: Sentry.EventHint): Sentry.Event | null => {
      // This can throw a runtime type error since we lost that hint can be null
      if (hint.originalException === "Timeout") {
        return null;
      }
      return event;
    },
  };
  Sentry.init(opts);

But it should be an error since hint is actually nullable. This has to do with how TypeScript treats all method declarations as having bivariant parameters (instead of contravariant parameters which is what we usually want). If we declare the interface as having properties that contain functions (instead of methods), the code snippet above no longer typechecks successfully (which is what we want).

// in Sentry (simplified)
interface Options {
  // forces contravariant parameter type checking
  beforeSend?: (event: Event, hint?: Hint) => Event | null;
}

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions