Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add GlobalThis type #511

Merged
merged 1 commit into from
Dec 8, 2022
Merged

Conversation

trevorade
Copy link
Contributor

@trevorade trevorade commented Nov 14, 2022

This type is for times when you need to access non-standard properties off of window, self, or globalThis. For example:

import type {GlobalThis} from 'type-fest';

interface ExtraProps extends GlobalThis {
  readonly GLOBAL_TOKEN: string;
}

const extraProps = globalThis as ExtraProps;
verifyToken(extraProps.GLOBAL_TOKEN);

Normally, you would define a declaration file to add global variables.

This change permits introducing global symbols in a more targeted manner.


Note: In the test, it seems like expectError should work here rather than using @ts-expect-error but, unfortunately, it does not.


I'd be happy to hear other suggestions on supporting this use case!

source/global-this.d.ts Outdated Show resolved Hide resolved
@sindresorhus
Copy link
Owner

I don't think we should support window and self. globalThis is the correct one to use for new code.

test-d/global-this.ts Outdated Show resolved Hide resolved
@trevorade trevorade force-pushed the global_this branch 2 times, most recently from c7dbcd9 to ed59727 Compare November 28, 2022 20:53
@trevorade
Copy link
Contributor Author

I don't think we should support window and self. globalThis is the correct one to use for new code.

Fair enough. Just need to guard our codebase from window usages :)

readme.md Outdated Show resolved Hide resolved
readme.md Outdated Show resolved Hide resolved
source/global-this.d.ts Outdated Show resolved Hide resolved
source/global-this.d.ts Outdated Show resolved Hide resolved
This type is for times when you need to access non-standard properties off of `window`, `self`, or `globalThis`. For example:

```ts
import type {GlobalThis} from 'type-fest';

interface ExtraProps extends GlobalThis {
  readonly GLOBAL_TOKEN: string;
}

const extraProps = window as ExtraProps;
```

---

Normally, you would define a declaration file to add global variables.

When you need to do this in a more targeted manner though, a common approach is:

```ts
interface ExtraProps extends Window {
  readonly GLOBAL_TOKEN: string
}

const extraProps = window as unknown as ExtraProps;
```

Without the cast through `unknown`, you get error `TS2352`.

You can try to workaround that with the following:

```ts
type GlobalThis = (typeof globalThis) & Window;
interface ExtraProps extends GlobalThis {
  readonly GLOBAL_TOKEN: string
}
```

But then you get the error: `Property 'Infinity' of type 'number' is not assignable to numeric index type 'Window'.(2412)` (also for `NaN`).

So you have to redefine `Infinity` and `NaN` as `never` to get this working.

---

Note: In environments that choose to not load the `"dom"` lib (e.g., for workers or node), the global `Window` interface will not be defined. The only way to modify `Infinity` and `NaN` would be to declare `Window` in the `global` scope. This is undesirable though as now an empty `Window` symbol will be present for users of `type-fest`. The workaround here is to make use of a `@ts-ignore` to treat `Window` as `any` if it is not present.
@sindresorhus
Copy link
Owner

Nice work 👍

@fregante
Copy link

I don't understand this type. Globals are global, what does "locally scoped properties on globalThis" even mean? What's the point of declaring globals if you're not sharing the types with your users? Should it even be global?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants