@total-typescript/ts-reset
Advanced tools
Comparing version 0.3.7 to 0.4.0
# @total-typescript/ts-reset | ||
## 0.4.0 | ||
### Minor Changes | ||
- ce9db42: Added support for widening in `Array.lastIndexOf`, `Array.indexOf`, `ReadonlyArray.lastIndexOf` and `ReadonlyArray.indexOf`. | ||
- 107dfc2: Changed the array.includes on readonly arrays to NOT be a type predicate. Before this change, this perfectly valid code would not behave correctly. | ||
```ts | ||
type Code = 0 | 1 | 2; | ||
type SpecificCode = 0 | 1; | ||
const currentCode: Code = 0; | ||
// Create an empty list of subset type | ||
const specificCodeList: ReadonlyArray<SpecificCode> = []; | ||
// This will be false, since 0 is not in [] | ||
if (specificCodeList.includes(currentCode)) { | ||
currentCode; // -> SpecificCode | ||
} else { | ||
// This branch will be entered, and ts will think z is 2, when it is actually 0 | ||
currentCode; // -> 2 | ||
} | ||
``` | ||
Removing the type predicate brings ts-reset closer towards correctness. | ||
- 4765413: author: @mefechoel | ||
Added the `Map.has` rule. | ||
Similar to `.includes` or `Set.has()`, `Map.has()` doesn't let you pass members that don't exist in the map's keys: | ||
```ts | ||
// BEFORE | ||
const userMap = new Map([ | ||
["matt", 0], | ||
["sofia", 1], | ||
[2, "waqas"], | ||
] as const); | ||
// Argument of type '"bryan"' is not assignable to | ||
// parameter of type '"matt" | "sofia" | "waqas"'. | ||
userMap.has("bryan"); | ||
``` | ||
With the rule enabled, `Map` follows the same semantics as `Set`. | ||
```ts | ||
// AFTER | ||
import "@total-typescript/ts-reset/map-has"; | ||
const userMap = new Map([ | ||
["matt", 0], | ||
["sofia", 1], | ||
[2, "waqas"], | ||
] as const); | ||
// .has now takes a string as the argument! | ||
userMap.has("bryan"); | ||
``` | ||
### Patch Changes | ||
- b15aaa4: Fixed an oversight with the initial `set-has` implementation by adding support to `ReadonlySet`. | ||
## 0.3.7 | ||
@@ -4,0 +70,0 @@ |
@@ -7,3 +7,3 @@ /// <reference path="utils.d.ts" /> | ||
fromIndex?: number, | ||
): searchElement is T; | ||
): boolean; | ||
} | ||
@@ -10,0 +10,0 @@ |
@@ -7,1 +7,3 @@ /// <reference path="fetch.d.ts" /> | ||
/// <reference path="set-has.d.ts" /> | ||
/// <reference path="map-has.d.ts" /> | ||
/// <reference path="array-index-of.d.ts" /> |
@@ -6,1 +6,5 @@ /// <reference path="utils.d.ts" /> | ||
} | ||
interface ReadonlySet<T> { | ||
has(value: T | (TSReset.WidenLiteral<T> & {})): boolean; | ||
} |
{ | ||
"name": "@total-typescript/ts-reset", | ||
"version": "0.3.7", | ||
"version": "0.4.0", | ||
"description": "A CSS reset for TypeScript, improving types for common JavaScript API's", | ||
@@ -52,2 +52,7 @@ "private": false, | ||
}, | ||
"./map-has": { | ||
"types": "./dist/map-has.d.ts", | ||
"import": "./dist/map-has.mjs", | ||
"default": "./dist/map-has.js" | ||
}, | ||
"./utils": { | ||
@@ -57,2 +62,7 @@ "types": "./dist/utils.d.ts", | ||
"default": "./dist/utils.js" | ||
}, | ||
"./array-index-of": { | ||
"types": "./dist/array-index-of.d.ts", | ||
"import": "./dist/array-index-of.mjs", | ||
"default": "./dist/array-index-of.js" | ||
} | ||
@@ -71,2 +81,11 @@ }, | ||
}, | ||
"prettier": { | ||
"arrowParens": "always", | ||
"trailingComma": "all", | ||
"semi": true, | ||
"printWidth": 80, | ||
"singleQuote": false, | ||
"tabWidth": 2, | ||
"useTabs": false | ||
}, | ||
"scripts": { | ||
@@ -73,0 +92,0 @@ "build": "tsx scripts/build.ts", |
# `ts-reset` | ||
Whenever you add TypeScript to a project, you're opting into **tens of thousands of lines of declaration files**. These files help describe JavaScript itself - `lib.dom.d.ts` describes the DOM, and `lib.d.ts` describes JavaScript itself. | ||
TypeScript's built-in typings are not perfect. `ts-reset` makes them better. | ||
These typings are not perfect. | ||
**Without `ts-reset`**: | ||
- `.json` (in `fetch`) and `JSON.parse` both return `any` | ||
- `.filter(Boolean)` doesn't behave how you expect | ||
- `array.includes` often breaks on readonly arrays | ||
- 🚨 `.json` (in `fetch`) and `JSON.parse` both return `any` | ||
- 🤦 `.filter(Boolean)` doesn't behave how you expect | ||
- 😡 `array.includes` often breaks on readonly arrays | ||
`ts-reset` smooths over these hard edges, just like a CSS reset does in the browser. You'll be able to: | ||
`ts-reset` smooths over these hard edges, just like a CSS reset does in the browser. | ||
- Prevent `any` entering your codebase | ||
- Make methods like `.filter` and `.includes` smarter | ||
**With `ts-reset`**: | ||
- 👍 `.json` (in `fetch`) and `JSON.parse` both return `unknown` | ||
- ✅ `.filter(Boolean)` behaves EXACTLY how you expect | ||
- 🥹 `array.includes` is widened to be more ergonomic | ||
- 🚀 And several more changes! | ||
## Example | ||
@@ -37,7 +41,8 @@ | ||
1. Install: `npm i @total-typescript/ts-reset` | ||
1. Install: `npm i -D @total-typescript/ts-reset` | ||
2. Import **once** into any `.ts` or `.tsx` file: | ||
2. Create a `reset.d.ts` file in your project with these contents: | ||
```ts | ||
// Do not add any other lines of code to this file! | ||
import "@total-typescript/ts-reset"; | ||
@@ -62,2 +67,4 @@ ``` | ||
For these imports to work, you'll need to ensure that, in your `tsconfig.json`, `module` is set to `NodeNext` or `Node16`. | ||
Below is a full list of all the rules available. | ||
@@ -186,17 +193,10 @@ | ||
It also makes `.includes` a type predicate, meaning you can use it to narrow wider types to a set enum: | ||
### Make `.indexOf` on `as const` arrays less strict | ||
```ts | ||
import "@total-typescript/ts-reset/array-includes"; | ||
import "@total-typescript/ts-reset/array-index-of"; | ||
``` | ||
const users = ["matt", "sofia", "waqas"] as const; | ||
Exactly the same behaviour of `.includes` (explained above), but for `.lastIndexOf` and `.indexOf`. | ||
const isUser = (input: string) => { | ||
if (users.includes(input)) { | ||
// input is narrowed to "matt" | "sofia" | "waqas" | ||
console.log(input); | ||
} | ||
}; | ||
``` | ||
### Make `Set.has()` less strict | ||
@@ -231,2 +231,39 @@ | ||
### Make `Map.has()` less strict | ||
```ts | ||
import "@total-typescript/ts-reset/map-has"; | ||
``` | ||
Similar to `.includes` or `Set.has()`, `Map.has()` doesn't let you pass members that don't exist in the map's keys: | ||
```ts | ||
// BEFORE | ||
const userMap = new Map([ | ||
["matt", 0], | ||
["sofia", 1], | ||
[2, "waqas"], | ||
] as const); | ||
// Argument of type '"bryan"' is not assignable to | ||
// parameter of type '"matt" | "sofia" | "waqas"'. | ||
userMap.has("bryan"); | ||
``` | ||
With the rule enabled, `Map` follows the same semantics as `Set`. | ||
```ts | ||
// AFTER | ||
import "@total-typescript/ts-reset/map-has"; | ||
const userMap = new Map([ | ||
["matt", 0], | ||
["sofia", 1], | ||
[2, "waqas"], | ||
] as const); | ||
// .has now takes a string as the argument! | ||
userMap.has("bryan"); | ||
``` | ||
### Removing `any[]` from `Array.isArray()` | ||
@@ -233,0 +270,0 @@ |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
19063
35
114
345