Skip to content

Commit

Permalink
Added rule to handle sessionStorage and localStorage
Browse files Browse the repository at this point in the history
  • Loading branch information
mattpocock committed Aug 10, 2023
1 parent 4d44ea0 commit 49b8603
Show file tree
Hide file tree
Showing 7 changed files with 114 additions and 0 deletions.
13 changes: 13 additions & 0 deletions .changeset/long-singers-help.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
---
"@total-typescript/ts-reset": minor
---

Added a rule, `/session`, to make sessionStorage and localStorage safer.

```ts
// Is now typed as `unknown`, not `any`!
localStorage.a;

// Is now typed as `unknown`, not `any`!
sessionStorage.abc;
```
5 changes: 5 additions & 0 deletions .changeset/wise-cycles-jam.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@total-typescript/ts-reset": minor
---

Added a `/dom` entrypoint to allow users to import DOM-only rules.
10 changes: 10 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,16 @@
"types": "./dist/array-index-of.d.ts",
"import": "./dist/array-index-of.mjs",
"default": "./dist/array-index-of.js"
},
"./dom": {
"types": "./dist/dom.d.ts",
"import": "./dist/dom.mjs",
"default": "./dist/dom.js"
},
"./storage": {
"types": "./dist/storage.d.ts",
"import": "./dist/storage.mjs",
"default": "./dist/storage.js"
}
},
"keywords": [],
Expand Down
34 changes: 34 additions & 0 deletions readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,19 @@ fetch("/")
});
```

### DOM Example

```ts
// Import from /dom to get DOM rules too!
import "@total-typescript/ts-reset/dom";

// localStorage just got safer!
localStorage.abc; // unknown

// sessionStorage just got safer!
sessionStorage.abc; // unknown
```

## Get Started

1. Install: `npm i -D @total-typescript/ts-reset`
Expand Down Expand Up @@ -293,6 +306,27 @@ const validate = (input: unknown) => {
};
```

### Making `sessionStorage` and `localStorage` safer

By default, `localStorage` and `sessionStorage` let you access any key, and return `any`:

```ts
// BEFORE

// No error!
localStorage.a.b.c.ohDear; // any
```

With this rule enabled, these keys now get typed as `unknown`:

```ts
// AFTER
import "@total-typescript/ts-reset/storage";

// Error!
localStorage.a.b.c.ohDear;
```

## Rules we won't add

### `Object.keys`/`Object.entries`
Expand Down
2 changes: 2 additions & 0 deletions src/entrypoints/dom.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
/// <reference path="recommended.d.ts" />
/// <reference path="storage.d.ts" />
3 changes: 3 additions & 0 deletions src/entrypoints/storage.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
interface Storage {
[name: string & {}]: unknown;
}
47 changes: 47 additions & 0 deletions src/tests/storage.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import { doNotExecute, Equal, Expect } from "./utils";

// Ensure that arbitrary access to localStorage is not allowed
doNotExecute(() => {
type test = Expect<Equal<typeof localStorage.a, unknown>>;

// @ts-expect-error
localStorage.a.b.c;
});

// Ensure that the type of localStorage remains correct
doNotExecute(() => {
type tests = [
Expect<Equal<typeof localStorage.getItem, (key: string) => string | null>>,
Expect<
Equal<typeof localStorage.setItem, (key: string, value: string) => void>
>,
Expect<Equal<typeof localStorage.removeItem, (key: string) => void>>,
Expect<Equal<typeof localStorage.clear, () => void>>,
Expect<Equal<typeof localStorage.key, (index: number) => string | null>>,
Expect<Equal<typeof localStorage.length, number>>,
];
});

// Ensure that arbitrary access to sessionStorage is not allowed
doNotExecute(() => {
type test = Expect<Equal<typeof sessionStorage.a, unknown>>;

// @ts-expect-error
sessionStorage.a.b.c;
});

// Ensure that the type of sessionStorage remains correct
doNotExecute(() => {
type tests = [
Expect<
Equal<typeof sessionStorage.getItem, (key: string) => string | null>
>,
Expect<
Equal<typeof sessionStorage.setItem, (key: string, value: string) => void>
>,
Expect<Equal<typeof sessionStorage.removeItem, (key: string) => void>>,
Expect<Equal<typeof sessionStorage.clear, () => void>>,
Expect<Equal<typeof sessionStorage.key, (index: number) => string | null>>,
Expect<Equal<typeof sessionStorage.length, number>>,
];
});

0 comments on commit 49b8603

Please sign in to comment.