fkhadra / fkhadra/react-toastify

Types: `ToastTransitionProps.position` is `ToastPosition | string` — should be `ToastPosition` (only the 6 positions have CSS)

Open
#1,288 0 comments 0 reactions 0 assignees View on GitHub
Dominant language
TypeScript
Stars
13.4k
Forks
741
PR merge metrics
No merged PRs in 30d

Description

## Describe the bug

`ToastTransitionProps.position` is typed `ToastPosition | string`, but every other place that describes
the same value uses the pure union `ToastPosition`, and the runtime only supports the six known positions.
The `| string` widens the union to plain `string` (TypeScript subsumes `'top-right' | … | string` into
`string`), so consumers of `ToastTransitionProps` — i.e. anyone writing a custom transition — lose all
type-safety and autocomplete on `position`, and the compiler will happily accept an invalid value that
produces no animation at runtime.

## Version

`react-toastify@11.1.0`

## Evidence

`dist/index.d.ts` (built types):

```ts
// line 99 — the public option
interface CommonOptions { position?: ToastPosition; ... }

// line 294 — internal toast props
interface ToastProps extends ToastOptions { position: ToastPosition; ... }

// line 278 — the outlier
interface ToastTransitionProps { position: ToastPosition | string; ... } // ⟵ should be ToastPosition
```

`ToastPosition` is the closed union:

```ts
type ToastPosition = 'top-right' | 'top-center' | 'top-left'
| 'bottom-right' | 'bottom-center' | 'bottom-left';
```

**Why `| string` is incorrect (not just imprecise):**

1. The transition builds its animation class by concatenation —
`const enterClassName = appendPosition ? \`${enter}--${position}\` : enter` — and the shipped CSS only
defines rules for the six known positions (`.Toastify__bounce-enter--top-left`, `--top-right`,
`--top-center`, `--bottom-left`, `--bottom-right`, `--bottom-center`). Any other string yields a class
like `Toastify__bounce-enter--whatever` that matches no rule → **no animation** (silent breakage).
2. The only value ever passed to a transition's `position` originates from the container/toast options,
which are typed `ToastPosition` (`CommonOptions.position?: ToastPosition`). So the `| string` arm is
never legitimately reachable through normal use.

## Expected behavior

```ts
interface ToastTransitionProps {
position: ToastPosition; // closed union, consistent with CommonOptions / ToastProps
}
```

This restores typo-safety and autocomplete for custom-transition authors and matches what the runtime
actually supports. (If arbitrary positions are intended to be supported in future, the fix would instead
be to add the corresponding CSS — but as shipped, the types are looser than the implementation.)

## How I found this

While generating ReScript type bindings from react-toastify's `.d.ts`, the binding for `` came out
as `position: string` (correct per the types) while `` came out as a proper 6-value enum —
the asymmetry traced back to this single `| string`. Filing since it looks like an unintended widening.

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.