grafana / grafana/plugin-tools
plugin-e2e: Window.grafanaBootData ambient type conflicts with @grafana/data's BootData (TS2717)
- Dominant language
- TypeScript
- Stars
- 89
- Forks
- 57
- Avg merge
- 3d 17h
- Merged PRs (30d)
- 37
Description
## What happened
`packages/plugin-e2e/src/index.ts` declares a global ambient augmentation:
```ts
declare global {
interface Window {
monaco: any;
grafanaBootData: {
settings: {
featureToggles: Record;
buildInfo: { version: string };
namespace: string;
};
};
}
}
```
Grafana core (`packages/grafana-data/src/types/config.ts` in grafana/grafana) declares its own,
much wider `BootData` type for the same `window.grafanaBootData`:
```ts
export interface BootData {
user: CurrentUserDTO;
settings: GrafanaConfig;
navTree: NavLinkDTO[];
assets: { light: string; dark: string };
_femt?: boolean;
}
```
When a single `tsc` program includes both this package's shipped `.d.ts` and Grafana's own
ambient declaration (e.g. a Grafana core tsconfig that typechecks both app source and
`@grafana/plugin-e2e`), TypeScript requires merged global interface property declarations to
have the *identical* type (TS2717: "Subsequent property declarations must have the same type").
The two shapes are structurally incompatible (plugin-e2e's is a strict, narrower subset), so
this is normally a hard compile error.
In grafana/grafana this is currently masked only because `skipLibCheck: true` is inherited from
the root tsconfig, which suppresses TS2717 for declaration files. With the error suppressed,
*which* declaration "wins" the merge for e2e-playwright type-checking depends on unspecified
compiler file-processing order — verified empirically: reversing an `include` array order in
Grafana's `e2e-playwright/tsconfig.json` flips which declaration wins and produces 3 real type
errors in `packages/grafana-runtime/src/config.ts` and
`packages/grafana-ui/src/components/DateTimePickers/WeekStartPicker.tsx`. Grafana currently
works around this with an "order matters" comment pinning the include order — a fragile
mechanism that a TS upgrade, a `skipLibCheck` change, or an innocent include-list reorder could
silently flip.
## Proposed fix
Type `grafanaBootData` as `import('@grafana/data').BootData` directly, so the merged property
is structurally identical to Grafana core's own declaration and TS2717 no longer applies
regardless of file order or `skipLibCheck`. I have this change ready locally (adds
`@grafana/data` as a `dependencies` entry of `plugin-e2e`, which it did not previously depend
on) and have verified it resolves the reversed-include-order regression in a local grafana/grafana
checkout. Happy to open a PR — wanted to raise the approach with maintainers first since it
changes this package's public ambient type surface and adds a new dependency.
### Caveat found during verification
The fix removes the *silent* TS2717 landmine, but if a consumer's own `@grafana/data` (e.g. via
workspace source) has drifted from the `@grafana/data` version `plugin-e2e` depends on, a
*different*, non-silent type error can still surface (duplicate-package type structural drift,
e.g. between two versions' `IconName` unions) — this is normal npm/yarn dependency duplication,
not a defect in this fix, but worth being aware of for anyone who also pins `@grafana/data`
narrowly.
## Environment
- `@grafana/plugin-e2e` 3.10.0
- Verified against `grafana/grafana` (branch cut from `origin/main`)
Contributor guide
Research direction
Review packages/plugin-e2e/src/index.ts alongside packages/grafana-data/src/types/config.ts to compare the two global grafanaBootData declarations. Reproduce the type-checking scenario with both declarations, then verify that the declarations no longer produce TS2717 and that reversing the e2e-playwright include order does not cause the reported errors in packages/grafana-runtime/src/config.ts or packages/grafana-ui/src/components/DateTimePickers/WeekStartPicker.tsx.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- typescript
- Domain
- tooling
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Quiet
- Clarity
- Clearly specified
- Newbie friendliness
- 48/100