Skip to content

Commit bd39b15

Browse files
authored
fix(types): allow global.Netlify declaration merging (#494)
* docs: fix misleading comments * fix(types): allow `global.Netlify` declaration merging This fixes a TypeScript error that occurs when both `@netlify/[email protected]` and `@netlify/functions` are installed in a project (with `skipLibCheck: false`). It would fail with: ``` Error: TS2451: Cannot redeclare block-scoped variable 'Netlify' ``` See for example #489. You would think it wouldn't be valid to use both those packages at once, but TypeScript global module augmentation is truly _global_ - it doesn't care where you import a package that performs global module augmentation; your whole TS project is compiled/typechecked as one program, unless you explicitly configure things completely separately for your `./netlify/functions` vs. `./netlify/edge-functions` vs. `src/`... which pretty much no one does. TypeScript allows multiple `var` declarations in a scope to merge, but `const` declarations are cannot be redeclared. When both packages declare `global.Netlify`, they must both use `var` for the declarations to merge successfully. We were actually already doing this correctly, but unfortunately there was a comment that was lying about _why_ (and there was no type test covering this). This led me to change it to `const` in #434. I went down a rabbit hole trying to add a regression type test for this but I had to cut my losses after running into some issues.
1 parent 9fe3782 commit bd39b15

File tree

3 files changed

+7
-7
lines changed

3 files changed

+7
-7
lines changed

packages/edge-functions/prod/src/main.ts

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,8 @@
11
import type { NetlifyGlobal } from '@netlify/types'
22

33
declare global {
4-
// Using `var` so that the declaration is hoisted in such a way that we can
5-
// reference it before it's initialized.
6-
4+
// Using `var` instead of `const` to allow TypeScript declaration merging.
5+
// Multiple packages can declare the same global with `var`, but `const` cannot be redeclared.
76
var Netlify: NetlifyGlobal
87
}
98

packages/functions/prod/src/main.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
import type { NetlifyGlobal } from '@netlify/types'
22

33
declare global {
4-
const Netlify: NetlifyGlobal
4+
// Using `var` instead of `const` to allow TypeScript declaration merging.
5+
// Multiple packages can declare the same global with `var`, but `const` cannot be redeclared.
6+
var Netlify: NetlifyGlobal
57
}
68

79
export { builder } from './lib/builder.js'

packages/runtime/src/lib/globals.ts

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,8 @@ import type { Context, NetlifyGlobal } from '@netlify/types'
44
import { GlobalScope } from './util.js'
55

66
declare global {
7-
// Using `var` so that the declaration is hoisted in such a way that we can
8-
// reference it before it's initialized.
9-
7+
// Using `var` instead of `const` to allow TypeScript declaration merging.
8+
// Multiple packages can declare the same global with `var`, but `const` cannot be redeclared.
109
var Netlify: NetlifyGlobal
1110
}
1211

0 commit comments

Comments
 (0)