├── .gitignore ├── .npmignore ├── .vscode └── settings.json ├── CHANGELOG.md ├── LICENSE ├── README.md ├── dev-tools └── changelog.js ├── package-lock.json ├── package.json ├── sources ├── document │ ├── _index.d.ts │ ├── addEventListener.d.ts │ ├── cloneNode.d.ts │ ├── currentTarget.ts │ ├── generators │ │ ├── .addEventListener.g.js │ │ └── .onEvent.g.js │ ├── onEvent.d.ts │ └── querySelector.d.ts ├── ecmascript │ ├── Array │ │ ├── _index.ts │ │ ├── indexof.d.ts │ │ ├── isarray.d.ts │ │ └── map.d.ts │ ├── index.d.ts │ └── object │ │ ├── _index.ts │ │ ├── create.ts │ │ ├── defineProperties.ts │ │ ├── defineProperty.d.ts │ │ ├── objectAssign.d.ts │ │ ├── objectKeys.ts │ │ └── setPrototypeOf.ts ├── index.d.ts └── utils │ ├── $research.ts │ ├── README.md │ └── index.ts ├── test-utility-types ├── .vscode │ └── settings.json ├── package.json ├── pnpm-lock.yaml ├── sources │ ├── ecma.ts │ └── index.ts └── tsconfig.json ├── tests ├── dom.ts ├── ecma.ts └── utility.ts ├── tests_origin ├── $__problems__research.ts ├── $__proposals.ts ├── dom.ts └── ecma.ts └── tsconfig.json /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules/ -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- 1 | node_modules/ 2 | tests/ 3 | tests_origin/ 4 | .vscode/ 5 | test-utility-types/ -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "typescript.tsdk": "node_modules/typescript/lib" 3 | } -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # changelog 2 | 3 | ## 2.2.6 4 | 5 | - utils: fixed `-?` for Optional types (as bad idea) 6 | - utils fixed: OptionalExcept fixed for older ts versions 7 | 8 | ## 2.2.3 9 | 10 | - utils added: OptionalExcept 11 | 12 | ## 2.2.2 13 | 14 | - utils added: Optional 15 | - add files section to package.json 16 | - ReduceBy example correction 17 | 18 | ## 2.2.0 19 | 20 | - PickByKey declined 21 | - DiscrimeBy is added to $research 22 | - Overlap and ReduceBy utility types are added 23 | 24 | ## 2.0.2 25 | 26 | - rename NonNullableKeys to NonNullableKey 27 | 28 | ## 2.0.1 29 | 30 | - add object types to _index reference 31 | - object arg for KeysArray instead of union 32 | - revert to KeysArray 33 | - replace KeysArray to KeysAsTuple 34 | - Update index.ts 35 | - Update $research.ts 36 | - rename required to nonnullable 37 | - window isTrust guard 38 | - drop node as default target inside onevents 39 | - G generic arg for the UIEvent for forcing spcifying targe type 40 | - add setPrototypeOf 41 | - IsUnion & UnionToIntersection 42 | - currentTarget fix win types 43 | - fix utility desc 44 | - drop keys 45 | - remove rollup config 46 | - Filter & KeysMatching utils 47 | - fix merge type args 48 | - fix paths in settings json 49 | - peerDependencies up 50 | - drop hooks 51 | - check hook 52 | - dom tests attached 53 | - utility types renaming -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2023 Sanshain 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # types-spring 2 | 3 | [![npm](https://img.shields.io/npm/v/types-spring)](https://www.npmjs.com/package/types-spring) 4 | [![npm](https://img.shields.io/npm/dm/types-spring)](https://www.npmjs.com/package/types-spring) 5 | 6 | A package that aims to eliminate some of the shortcomings of the built-in types in standard ts libraries and deliver additional utility types that will facilitate daily work. Inspired by [ts-reset](https://github.com/total-typescript/ts-reset). 7 | 8 | ## Built-in types features: 9 | 10 | ### Array.map 11 | 12 | #### before: 13 | 14 | ```ts 15 | const a = [1, 2, 3] as const; 16 | let arr = a.map(r => r + '') // string[] 17 | ``` 18 | 19 | #### after: 20 | 21 | ```ts 22 | const a = [1, 2, 3] as const; 23 | let arr = a.map(r => r + '') // [string, string, string] 24 | ``` 25 | 26 | ### Array.isArray 27 | 28 | #### before: 29 | 30 | ```ts 31 | function checkArray(a: { a: 1 } | ReadonlyArray) 32 | { 33 | if (Array.isArray(a)) { 34 | a.forEach(item => item.f()) // => runtime error! 35 | } 36 | else { a.a } // type error: property `a` does not exists! 37 | } 38 | ``` 39 | 40 | #### after: 41 | 42 | ```ts 43 | function checkArray(a: { a: 1 } | ReadonlyArray) 44 | { 45 | if (Array.isArray(a)) { 46 | a.forEach(item => item.f()) // type error: f does not exist on type number 47 | } 48 | else { a.a } // success 49 | } 50 | ``` 51 | 52 | ### Object.create 53 | 54 | #### before: 55 | ```ts 56 | let o = Object.create({}) // any 57 | ``` 58 | 59 | #### after: 60 | ```ts 61 | let o = Object.create({}) // object 62 | ``` 63 | 64 | ### Object.assign 65 | 66 | #### before: 67 | 68 | ```ts 69 | let t = Object.assign({ a: 7, b: 8 }, { b: '' }) // {a: number, b: never} 70 | ``` 71 | 72 | #### after: 73 | 74 | ```ts 75 | let t = Object.assign({ a: 7, b: 8 }, { b: '' }) // {a: number, b: string} 76 | ``` 77 | 78 | ### Object.defineProperty 79 | 80 | #### before: 81 | 82 | ```ts 83 | const a = { a: 1 } 84 | const r = Object.defineProperty(a, "b", { value: 1, }); // {a: number} 85 | ``` 86 | 87 | #### after: 88 | 89 | ```ts 90 | const a = { a: 1 } 91 | const r = Object.defineProperty(a, "b", { value: 1, }); // {a: number, readonly b: number} 92 | ``` 93 | 94 | ### Object.defineProperties 95 | 96 | #### before: 97 | 98 | ```ts 99 | const a = { a: 1 } 100 | const rs = Object.defineProperties({ a: 1 }, { // {a: number} 101 | b: { value: 1 } 102 | }); 103 | ``` 104 | 105 | #### after: 106 | 107 | ```ts 108 | const a = { a: 1 } 109 | const rs = Object.defineProperties({ a: 1 }, { // {a: number, readonly b: number} 110 | b: { value: 1 } 111 | }); 112 | ``` 113 | 114 | 115 | 116 | ### Object.keys 117 | 118 | A very strong temptation was to make an `Object.keys(obj)` returned `(keys of obj)[]` instead of `string[]`. However, in the process it was found out that such use is safe only if the received keys are used exclusively for comparison with primitives. But using them again as object type keys can lead to non-obvious errors at runtime (see for [example](https://www.typescriptlang.org/play?#code/JYOwLgpgTgZghgYwgAgPICMBWEFgMID2IAzmFAK64FTIDeAUMk8gPQBUbjzybyAShDDkoJZGAAWKEHAC2EYsgIwxk5BBDk5UOOgA2KUlFABzZAAcoBM9DDB5yOCAAmyORIJOFShyEVYcYAB0XMy8AAJmcNoyimj+uCpwYMgIRGBwoAoSKBZWNnYKji5u4h7EgcgAKuLACgiOyOgoDQTxyRJJyACeBOQpUBBJEC7UPmoAHrW2IKYAIgQImurJGNgJALIeELrIABSzqOsAlH5rQSFMbCzcFwDWEF3EADyVE5DOXm0AfLsEAFxVI4AgCCUG0XSe9x6ykqXwA3BdlkZ5C83upPKcAj9-oCQWC4BCANpQ7yVAA0VWJD1JAF0afDuDcAL70eipEjJYgEOSrAG0BwAjQyJpQOGNQWaEVihAS4XQZBM5AAXjoAuQAEYAAwU9AAgBM2pSAIAzJqFWyiKRkFyeVg9Xy1UKpeLkE75YqVTaIKtWeyrTACAQmCrdlDiHjwZDqcowF1rN4vas9V8TkqvnQLn7kjI4GY+YSANLIUDIEkxuMQBPc712ml8gM4t1QJke1VwB0NgFahU6juB-Vmlus7gDIQiUsPco5syhh7K9PTqldGmBBsnJgsa4UcDAORqMHUACE9BZ9Abu1WAUCYd2ibtRyOQA), which will cause a runtime error). Thus, the usual redefinition of the type makes it less secure, and therefore we have abandoned such redefinition in this package. However, if you are determined, there is a safe way for you to do this using the [ts-keys-turn](https://github.com/Sanshain/ts-keys-turn) package 119 | 120 |
121 |

Object.keys with `ts-keys-turn`

122 | 123 | #### before: 124 | 125 | ```ts 126 | type O = { a: number, b: number } 127 | const obj: O = { a: 1, b: 1 } 128 | const keys = Object.keys(obj) // string[] 129 | ``` 130 | 131 | #### after ts-keys-turn: 132 | 133 | ```ts 134 | const keys = Object.keys(obj) // ("a" | "b")[] 135 | ``` 136 | 137 | However, this approach has several constraints (see the [documentation](https://github.com/Sanshain/ts-keys-turn#constraints)) 138 | 139 | 140 | 141 |
142 | 143 | Look up the section on configuring the package for use with [Object.keys](https://github.com/Sanshain/ts-keys-turn/blob/master/README.md#using-keys-for-transformataion-requires-the-following-steps) 144 | 145 |
146 |

Object.keys with unsafe branch

147 | 148 | There is also an [unsafe branch](https://github.com/Sanshain/types-spring/tree/unsafe) that contains the aforementioned `Object.keys` declaration, which assumes its use without any transformations, if you are willing to take responsibility for its use as keys 149 | 150 | ```ts 151 | const keys = Object.keys({a: 1, b: 1}) // ("a" | "b")[] 152 | ``` 153 | 154 |
155 | 156 | 157 | ## DOM features: 158 | 159 | ### querySelector 160 | 161 | Improves detecting Element type from selector signature. 162 | 163 | #### before: 164 | 165 | 166 | ```ts 167 | const input = document.querySelector('input'); // is HTMLInputElement | null 168 | const unknown = document.querySelector('.cls'); // is Element | null 169 | const inputWCls = document.querySelector('input.cls'); // is Element | null 170 | 171 | if (divCls) { 172 | inputWCls.value = '' // error 173 | } 174 | ``` 175 | 176 | #### after: 177 | 178 | ```ts 179 | const input = document.querySelector('input'); // is HTMLInputElement | null 180 | const unknown = document.querySelector('.cls'); // is Element | null 181 | const inputWCls = document.querySelector('input.cls'); // is HTMLInputElement | null 182 | if (divCls) { 183 | inputWCls.value = '' // success 184 | } 185 | ``` 186 | 187 | ### querySelector\ 188 | 189 | Original `querySelector` required just to use generic to specify returned type that may differ from the runtime: 190 | 191 | #### before: 192 | 193 | ```ts 194 | const misspell = document.querySelector('a.cls'); // is HTMLInputElement | null 195 | if (misspell){ 196 | const replaced = misspell.value.replace('.', ',') // runtime error! 197 | } 198 | ``` 199 | 200 | #### after: 201 | 202 | ```ts 203 | const misspell = document.querySelector('a.cls'); // is HTMLInputElement | null 204 | if (misspell){ 205 | const replaced = misspell.value.replace('.', ',') // typescript error! 206 | } 207 | ``` 208 | 209 | ### cloneNode 210 | 211 | Now `HTMLElement.cloneNode` allways returns `HTMLElement`: 212 | 213 | #### before: 214 | 215 | ```ts 216 | const elem = document.getElementById('id') // elem is HTMLElement 217 | const clonedElem = elem?.cloneNode() // clonedElem is Node 218 | ``` 219 | 220 | #### after: 221 | 222 | ```ts 223 | const elem = document.getElementById('id') // elem is HTMLElement 224 | const clonedElem = elem?.cloneNode() // clonedElem is HTMLElement also 225 | ``` 226 | 227 | 228 | ### currentTarget 229 | 230 | Improved automatic type detection for the `currentTarget` in `MouseEvent`, `KeyboardEvent` and other user interface events (only inside `addEventListener` callback): 231 | 232 | #### before: 233 | 234 | ```ts 235 | let elem: HTMLDivElement = document.querySelector('div'); 236 | elem?.addEventListener('click', e => { 237 | let target = e.currentTarget; // is EventTarget | null 238 | }) 239 | ``` 240 | 241 | 242 | #### after: 243 | 244 | ```ts 245 | let elem: HTMLDivElement = document.querySelector('div'); 246 | elem?.addEventListener('click', e => { 247 | let target = e.currentTarget; // is HTMLDivElement | null 248 | }) 249 | ``` 250 | 251 | 252 | ## Utility types: 253 | 254 | Look up `README.md` inside corresponding [declaration](https://github.com/Sanshain/types-spring/tree/master/sources/utils) directory. 255 | 256 | 257 | 258 | ## How to use 259 | 260 | ```ts 261 | npm i -D types-spring 262 | ``` 263 | 264 | #### To patch the built-in types: 265 | 266 | add types-spring to include list inside tsconfig.json: 267 | 268 | ```tsconfig.json 269 | { 270 | // ..., 271 | "include": [ 272 | "./node_modules/**/*" 273 | ] 274 | } 275 | ``` 276 | 277 | ## Similar packages: 278 | 279 | ## ts-reset 280 | 281 | As it was said at the beginning, this package was inspired by [ts-reset](https://github.com/total-typescript/ts-reset). At first glance, it seemed that the `ts-reset` does very little: it just overrides in tslib `any` to `unknown` type wherever possible, and contains two useful improvements for `Array.indexOf` and `Array.filter`. However despite the fact that in this one there are not so much features, it is very profound and I would say that the author is very scrupulous about safing. 282 | 283 | #### Compatibility 284 | 285 | Despite the small contribution of ts-reset, I was very tempted to use some of its functions in types-spring, but I deliberately did not do it in order not to repeat what other people have already done in the best possible way before me. I consider `ts-reset` as be a fundamental package, and the best thing to do today is to use these two these packages (`ts-reset` and `types-spring`) together 286 | 287 | ## types-fest 288 | 289 | This is a [awesome package](https://github.com/sindresorhus/type-fest) with a huge number of utility types. When I started working on types-string, I didn't know anything about it. However, when I got awared, to my surprise found that most of them (with the exception of just two) do not overlap with `types-spring`! It turns out that these are completely different packages with different tools, since their authors think differently. 290 | 291 | #### Compatibility 292 | 293 | `types-spring` and `types-fest` may well complement each other. Of course, that's so 294 | 295 | ## Licence 296 | 297 | MIT 298 | 299 | ![GitHub](https://img.shields.io/github/license/Sanshain/types-spring) 300 | -------------------------------------------------------------------------------- /dev-tools/changelog.js: -------------------------------------------------------------------------------- 1 | //@ts-check 2 | 3 | const fs = require('fs'); 4 | const { execSync } = require('child_process') 5 | 6 | 7 | const CHANGELOG = 'CHANGELOG.md' 8 | 9 | 10 | const packageConfig = fs.readFileSync('package.json').toString() 11 | 12 | 13 | 14 | var [lastVer, lastLog] = getLastVer(); 15 | 16 | const package = JSON.parse(packageConfig) 17 | if (package.version !== lastVer) { 18 | const log = execSync('git log --oneline').toString(); 19 | const lines = log.split('\n') 20 | .map(title => title.replace(/\([\s\S]+\)/, '')) // remove current branch name 21 | .map(line => line.split(' ').slice(1).join(' ')) // remove commit hash 22 | .filter(w => !w.match(/(readme|merge branch|npmignore|gitignore)/i)) // remove service commits by specifying keywords 23 | .filter(title => !title.match(/^[\w\d\-_]+$/m)) // remove one-word commits as useless info 24 | .filter(title => title.length > 6) // remove too short commit names as useless 25 | 26 | 27 | console.log(lines); 28 | let newLog = '' 29 | for (const line of lines) { 30 | if (lastLog == line) break; 31 | newLog += line + '. ' 32 | } 33 | 34 | if (newLog) { 35 | fs.writeFileSync(CHANGELOG, `${package.version} - ${newLog}\n` + log); 36 | } 37 | } 38 | 39 | 40 | 41 | function getLastVer() { 42 | if (fs.existsSync(CHANGELOG)) { 43 | const log = fs.readFileSync(CHANGELOG).toString(); 44 | const lastVerInfo = log.split('\n')[0] 45 | const verInfo = lastVerInfo.match(/(?\d+.\d+.\d+)b? - (?[\s\S]+)/); 46 | if (verInfo) { 47 | return [verInfo.groups?.ver, verInfo.groups?.log]; 48 | } 49 | } 50 | return []; 51 | } 52 | 53 | -------------------------------------------------------------------------------- /package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "types-spring", 3 | "version": "2.0.2", 4 | "lockfileVersion": 2, 5 | "requires": true, 6 | "packages": { 7 | "": { 8 | "name": "types-spring", 9 | "version": "2.0.2", 10 | "license": "MIT", 11 | "devDependencies": { 12 | "@types/node": "^20.2.5", 13 | "npm-changelog": "^1.1.6", 14 | "simple-git-hooks": "^2.8.1", 15 | "typescript": "^5.0.4" 16 | }, 17 | "peerDependencies": { 18 | "typescript": "^4.7.4 || ^5.0.4" 19 | } 20 | }, 21 | "node_modules/@jridgewell/gen-mapping": { 22 | "version": "0.3.3", 23 | "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.3.tgz", 24 | "integrity": "sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ==", 25 | "dev": true, 26 | "optional": true, 27 | "dependencies": { 28 | "@jridgewell/set-array": "^1.0.1", 29 | "@jridgewell/sourcemap-codec": "^1.4.10", 30 | "@jridgewell/trace-mapping": "^0.3.9" 31 | }, 32 | "engines": { 33 | "node": ">=6.0.0" 34 | } 35 | }, 36 | "node_modules/@jridgewell/resolve-uri": { 37 | "version": "3.1.2", 38 | "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", 39 | "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", 40 | "dev": true, 41 | "optional": true, 42 | "engines": { 43 | "node": ">=6.0.0" 44 | } 45 | }, 46 | "node_modules/@jridgewell/set-array": { 47 | "version": "1.1.2", 48 | "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.2.tgz", 49 | "integrity": "sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==", 50 | "dev": true, 51 | "optional": true, 52 | "engines": { 53 | "node": ">=6.0.0" 54 | } 55 | }, 56 | "node_modules/@jridgewell/source-map": { 57 | "version": "0.3.5", 58 | "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.5.tgz", 59 | "integrity": "sha512-UTYAUj/wviwdsMfzoSJspJxbkH5o1snzwX0//0ENX1u/55kkZZkcTZP6u9bwKGkv+dkk9at4m1Cpt0uY80kcpQ==", 60 | "dev": true, 61 | "optional": true, 62 | "dependencies": { 63 | "@jridgewell/gen-mapping": "^0.3.0", 64 | "@jridgewell/trace-mapping": "^0.3.9" 65 | } 66 | }, 67 | "node_modules/@jridgewell/sourcemap-codec": { 68 | "version": "1.4.15", 69 | "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz", 70 | "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==", 71 | "dev": true, 72 | "optional": true 73 | }, 74 | "node_modules/@jridgewell/trace-mapping": { 75 | "version": "0.3.22", 76 | "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.22.tgz", 77 | "integrity": "sha512-Wf963MzWtA2sjrNt+g18IAln9lKnlRp+K2eH4jjIoF1wYeq3aMREpG09xhlhdzS0EjwU7qmUJYangWa+151vZw==", 78 | "dev": true, 79 | "optional": true, 80 | "dependencies": { 81 | "@jridgewell/resolve-uri": "^3.1.0", 82 | "@jridgewell/sourcemap-codec": "^1.4.14" 83 | } 84 | }, 85 | "node_modules/@rollup/plugin-terser": { 86 | "version": "0.4.4", 87 | "resolved": "https://registry.npmjs.org/@rollup/plugin-terser/-/plugin-terser-0.4.4.tgz", 88 | "integrity": "sha512-XHeJC5Bgvs8LfukDwWZp7yeqin6ns8RTl2B9avbejt6tZqsqvVoWI7ZTQrcNsfKEDWBTnTxM8nMDkO2IFFbd0A==", 89 | "dev": true, 90 | "optional": true, 91 | "dependencies": { 92 | "serialize-javascript": "^6.0.1", 93 | "smob": "^1.0.0", 94 | "terser": "^5.17.4" 95 | }, 96 | "engines": { 97 | "node": ">=14.0.0" 98 | }, 99 | "peerDependencies": { 100 | "rollup": "^2.0.0||^3.0.0||^4.0.0" 101 | }, 102 | "peerDependenciesMeta": { 103 | "rollup": { 104 | "optional": true 105 | } 106 | } 107 | }, 108 | "node_modules/@types/node": { 109 | "version": "20.2.5", 110 | "resolved": "https://registry.npmjs.org/@types/node/-/node-20.2.5.tgz", 111 | "integrity": "sha512-JJulVEQXmiY9Px5axXHeYGLSjhkZEnD+MDPDGbCbIAbMslkKwmygtZFy1X6s/075Yo94sf8GuSlFfPzysQrWZQ==", 112 | "dev": true 113 | }, 114 | "node_modules/acorn": { 115 | "version": "8.11.3", 116 | "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.3.tgz", 117 | "integrity": "sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg==", 118 | "dev": true, 119 | "optional": true, 120 | "bin": { 121 | "acorn": "bin/acorn" 122 | }, 123 | "engines": { 124 | "node": ">=0.4.0" 125 | } 126 | }, 127 | "node_modules/buffer-from": { 128 | "version": "1.1.2", 129 | "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", 130 | "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", 131 | "dev": true, 132 | "optional": true 133 | }, 134 | "node_modules/commander": { 135 | "version": "2.20.3", 136 | "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", 137 | "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", 138 | "dev": true, 139 | "optional": true 140 | }, 141 | "node_modules/npm-changelog": { 142 | "version": "1.1.6", 143 | "resolved": "https://registry.npmjs.org/npm-changelog/-/npm-changelog-1.1.6.tgz", 144 | "integrity": "sha512-n0/C9bnmE5LUSt0QCWu7eMiL8diftxT/QP3/YKQ8jMaIvdLRtvndwsMqg9j4WLxU7HHR/pAS5ou0Wei4aOF7iQ==", 145 | "dev": true, 146 | "bin": { 147 | "changeLog": "bin/bin.js" 148 | }, 149 | "optionalDependencies": { 150 | "@rollup/plugin-terser": "^0.4.4" 151 | }, 152 | "peerDependencies": { 153 | "simple-git-hooks": "^2.8.1" 154 | } 155 | }, 156 | "node_modules/randombytes": { 157 | "version": "2.1.0", 158 | "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", 159 | "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", 160 | "dev": true, 161 | "optional": true, 162 | "dependencies": { 163 | "safe-buffer": "^5.1.0" 164 | } 165 | }, 166 | "node_modules/safe-buffer": { 167 | "version": "5.2.1", 168 | "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", 169 | "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", 170 | "dev": true, 171 | "funding": [ 172 | { 173 | "type": "github", 174 | "url": "https://github.com/sponsors/feross" 175 | }, 176 | { 177 | "type": "patreon", 178 | "url": "https://www.patreon.com/feross" 179 | }, 180 | { 181 | "type": "consulting", 182 | "url": "https://feross.org/support" 183 | } 184 | ], 185 | "optional": true 186 | }, 187 | "node_modules/serialize-javascript": { 188 | "version": "6.0.2", 189 | "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.2.tgz", 190 | "integrity": "sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g==", 191 | "dev": true, 192 | "optional": true, 193 | "dependencies": { 194 | "randombytes": "^2.1.0" 195 | } 196 | }, 197 | "node_modules/simple-git-hooks": { 198 | "version": "2.8.1", 199 | "resolved": "https://registry.npmjs.org/simple-git-hooks/-/simple-git-hooks-2.8.1.tgz", 200 | "integrity": "sha512-DYpcVR1AGtSfFUNzlBdHrQGPsOhuuEJ/FkmPOOlFysP60AHd3nsEpkGq/QEOdtUyT1Qhk7w9oLmFoMG+75BDog==", 201 | "dev": true, 202 | "hasInstallScript": true, 203 | "bin": { 204 | "simple-git-hooks": "cli.js" 205 | } 206 | }, 207 | "node_modules/smob": { 208 | "version": "1.4.1", 209 | "resolved": "https://registry.npmjs.org/smob/-/smob-1.4.1.tgz", 210 | "integrity": "sha512-9LK+E7Hv5R9u4g4C3p+jjLstaLe11MDsL21UpYaCNmapvMkYhqCV4A/f/3gyH8QjMyh6l68q9xC85vihY9ahMQ==", 211 | "dev": true, 212 | "optional": true 213 | }, 214 | "node_modules/source-map": { 215 | "version": "0.6.1", 216 | "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", 217 | "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", 218 | "dev": true, 219 | "optional": true, 220 | "engines": { 221 | "node": ">=0.10.0" 222 | } 223 | }, 224 | "node_modules/source-map-support": { 225 | "version": "0.5.21", 226 | "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", 227 | "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", 228 | "dev": true, 229 | "optional": true, 230 | "dependencies": { 231 | "buffer-from": "^1.0.0", 232 | "source-map": "^0.6.0" 233 | } 234 | }, 235 | "node_modules/terser": { 236 | "version": "5.27.1", 237 | "resolved": "https://registry.npmjs.org/terser/-/terser-5.27.1.tgz", 238 | "integrity": "sha512-29wAr6UU/oQpnTw5HoadwjUZnFQXGdOfj0LjZ4sVxzqwHh/QVkvr7m8y9WoR4iN3FRitVduTc6KdjcW38Npsug==", 239 | "dev": true, 240 | "optional": true, 241 | "dependencies": { 242 | "@jridgewell/source-map": "^0.3.3", 243 | "acorn": "^8.8.2", 244 | "commander": "^2.20.0", 245 | "source-map-support": "~0.5.20" 246 | }, 247 | "bin": { 248 | "terser": "bin/terser" 249 | }, 250 | "engines": { 251 | "node": ">=10" 252 | } 253 | }, 254 | "node_modules/typescript": { 255 | "version": "5.0.4", 256 | "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.0.4.tgz", 257 | "integrity": "sha512-cW9T5W9xY37cc+jfEnaUvX91foxtHkza3Nw3wkoF4sSlKn0MONdkdEndig/qPBWXNkmplh3NzayQzCiHM4/hqw==", 258 | "dev": true, 259 | "bin": { 260 | "tsc": "bin/tsc", 261 | "tsserver": "bin/tsserver" 262 | }, 263 | "engines": { 264 | "node": ">=12.20" 265 | } 266 | } 267 | }, 268 | "dependencies": { 269 | "@jridgewell/gen-mapping": { 270 | "version": "0.3.3", 271 | "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.3.tgz", 272 | "integrity": "sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ==", 273 | "dev": true, 274 | "optional": true, 275 | "requires": { 276 | "@jridgewell/set-array": "^1.0.1", 277 | "@jridgewell/sourcemap-codec": "^1.4.10", 278 | "@jridgewell/trace-mapping": "^0.3.9" 279 | } 280 | }, 281 | "@jridgewell/resolve-uri": { 282 | "version": "3.1.2", 283 | "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", 284 | "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", 285 | "dev": true, 286 | "optional": true 287 | }, 288 | "@jridgewell/set-array": { 289 | "version": "1.1.2", 290 | "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.2.tgz", 291 | "integrity": "sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==", 292 | "dev": true, 293 | "optional": true 294 | }, 295 | "@jridgewell/source-map": { 296 | "version": "0.3.5", 297 | "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.5.tgz", 298 | "integrity": "sha512-UTYAUj/wviwdsMfzoSJspJxbkH5o1snzwX0//0ENX1u/55kkZZkcTZP6u9bwKGkv+dkk9at4m1Cpt0uY80kcpQ==", 299 | "dev": true, 300 | "optional": true, 301 | "requires": { 302 | "@jridgewell/gen-mapping": "^0.3.0", 303 | "@jridgewell/trace-mapping": "^0.3.9" 304 | } 305 | }, 306 | "@jridgewell/sourcemap-codec": { 307 | "version": "1.4.15", 308 | "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz", 309 | "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==", 310 | "dev": true, 311 | "optional": true 312 | }, 313 | "@jridgewell/trace-mapping": { 314 | "version": "0.3.22", 315 | "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.22.tgz", 316 | "integrity": "sha512-Wf963MzWtA2sjrNt+g18IAln9lKnlRp+K2eH4jjIoF1wYeq3aMREpG09xhlhdzS0EjwU7qmUJYangWa+151vZw==", 317 | "dev": true, 318 | "optional": true, 319 | "requires": { 320 | "@jridgewell/resolve-uri": "^3.1.0", 321 | "@jridgewell/sourcemap-codec": "^1.4.14" 322 | } 323 | }, 324 | "@rollup/plugin-terser": { 325 | "version": "0.4.4", 326 | "resolved": "https://registry.npmjs.org/@rollup/plugin-terser/-/plugin-terser-0.4.4.tgz", 327 | "integrity": "sha512-XHeJC5Bgvs8LfukDwWZp7yeqin6ns8RTl2B9avbejt6tZqsqvVoWI7ZTQrcNsfKEDWBTnTxM8nMDkO2IFFbd0A==", 328 | "dev": true, 329 | "optional": true, 330 | "requires": { 331 | "serialize-javascript": "^6.0.1", 332 | "smob": "^1.0.0", 333 | "terser": "^5.17.4" 334 | } 335 | }, 336 | "@types/node": { 337 | "version": "20.2.5", 338 | "resolved": "https://registry.npmjs.org/@types/node/-/node-20.2.5.tgz", 339 | "integrity": "sha512-JJulVEQXmiY9Px5axXHeYGLSjhkZEnD+MDPDGbCbIAbMslkKwmygtZFy1X6s/075Yo94sf8GuSlFfPzysQrWZQ==", 340 | "dev": true 341 | }, 342 | "acorn": { 343 | "version": "8.11.3", 344 | "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.3.tgz", 345 | "integrity": "sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg==", 346 | "dev": true, 347 | "optional": true 348 | }, 349 | "buffer-from": { 350 | "version": "1.1.2", 351 | "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", 352 | "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", 353 | "dev": true, 354 | "optional": true 355 | }, 356 | "commander": { 357 | "version": "2.20.3", 358 | "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", 359 | "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", 360 | "dev": true, 361 | "optional": true 362 | }, 363 | "npm-changelog": { 364 | "version": "1.1.6", 365 | "resolved": "https://registry.npmjs.org/npm-changelog/-/npm-changelog-1.1.6.tgz", 366 | "integrity": "sha512-n0/C9bnmE5LUSt0QCWu7eMiL8diftxT/QP3/YKQ8jMaIvdLRtvndwsMqg9j4WLxU7HHR/pAS5ou0Wei4aOF7iQ==", 367 | "dev": true, 368 | "requires": { 369 | "@rollup/plugin-terser": "^0.4.4" 370 | } 371 | }, 372 | "randombytes": { 373 | "version": "2.1.0", 374 | "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", 375 | "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", 376 | "dev": true, 377 | "optional": true, 378 | "requires": { 379 | "safe-buffer": "^5.1.0" 380 | } 381 | }, 382 | "safe-buffer": { 383 | "version": "5.2.1", 384 | "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", 385 | "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", 386 | "dev": true, 387 | "optional": true 388 | }, 389 | "serialize-javascript": { 390 | "version": "6.0.2", 391 | "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.2.tgz", 392 | "integrity": "sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g==", 393 | "dev": true, 394 | "optional": true, 395 | "requires": { 396 | "randombytes": "^2.1.0" 397 | } 398 | }, 399 | "simple-git-hooks": { 400 | "version": "2.8.1", 401 | "resolved": "https://registry.npmjs.org/simple-git-hooks/-/simple-git-hooks-2.8.1.tgz", 402 | "integrity": "sha512-DYpcVR1AGtSfFUNzlBdHrQGPsOhuuEJ/FkmPOOlFysP60AHd3nsEpkGq/QEOdtUyT1Qhk7w9oLmFoMG+75BDog==", 403 | "dev": true 404 | }, 405 | "smob": { 406 | "version": "1.4.1", 407 | "resolved": "https://registry.npmjs.org/smob/-/smob-1.4.1.tgz", 408 | "integrity": "sha512-9LK+E7Hv5R9u4g4C3p+jjLstaLe11MDsL21UpYaCNmapvMkYhqCV4A/f/3gyH8QjMyh6l68q9xC85vihY9ahMQ==", 409 | "dev": true, 410 | "optional": true 411 | }, 412 | "source-map": { 413 | "version": "0.6.1", 414 | "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", 415 | "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", 416 | "dev": true, 417 | "optional": true 418 | }, 419 | "source-map-support": { 420 | "version": "0.5.21", 421 | "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", 422 | "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", 423 | "dev": true, 424 | "optional": true, 425 | "requires": { 426 | "buffer-from": "^1.0.0", 427 | "source-map": "^0.6.0" 428 | } 429 | }, 430 | "terser": { 431 | "version": "5.27.1", 432 | "resolved": "https://registry.npmjs.org/terser/-/terser-5.27.1.tgz", 433 | "integrity": "sha512-29wAr6UU/oQpnTw5HoadwjUZnFQXGdOfj0LjZ4sVxzqwHh/QVkvr7m8y9WoR4iN3FRitVduTc6KdjcW38Npsug==", 434 | "dev": true, 435 | "optional": true, 436 | "requires": { 437 | "@jridgewell/source-map": "^0.3.3", 438 | "acorn": "^8.8.2", 439 | "commander": "^2.20.0", 440 | "source-map-support": "~0.5.20" 441 | } 442 | }, 443 | "typescript": { 444 | "version": "5.0.4", 445 | "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.0.4.tgz", 446 | "integrity": "sha512-cW9T5W9xY37cc+jfEnaUvX91foxtHkza3Nw3wkoF4sSlKn0MONdkdEndig/qPBWXNkmplh3NzayQzCiHM4/hqw==", 447 | "dev": true 448 | } 449 | } 450 | } 451 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "types-spring", 3 | "version": "2.2.6", 4 | "description": "a package that provides more accurate and powerful typescript capabilities", 5 | "types": "./sources/utils/index.ts", 6 | "exports": { 7 | ".": { 8 | "types": "./sources/index.d.ts" 9 | }, 10 | "./utils": { 11 | "types": "./sources/utils/index.ts" 12 | } 13 | }, 14 | "scripts": { 15 | "test": "tsc --noEmit", 16 | "$log": "node ./dev-tools/changelog.js", 17 | "changelog": "changelog --titled", 18 | "hooks": "simple-git-hooks" 19 | }, 20 | "simple-git-hooks": { 21 | "pre-push": "npm run log" 22 | }, 23 | "keywords": [ 24 | "typescript", 25 | "types" 26 | ], 27 | "repository": { 28 | "url": "https://github.com/Sanshain/types-spring.git", 29 | "type": "git" 30 | }, 31 | "homepage": "https://github.com/Sanshain/types-spring", 32 | "author": "Sanshain", 33 | "license": "MIT", 34 | "peerDependencies": { 35 | "typescript": "^4.7.4 || ^5.0.4" 36 | }, 37 | "devDependencies": { 38 | "@types/node": "^20.2.5", 39 | "npm-changelog": "^1.1.6", 40 | "simple-git-hooks": "^2.8.1", 41 | "typescript": "^5.0.4" 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /sources/document/_index.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | /// 3 | /// 4 | 5 | 6 | 7 | 8 | // interface HTMLElement { 9 | // onclick: ((ev: MouseEvent) => any) | null; 10 | // // onclick: ((this: GlobalEventHandlers, ev: MouseEvent) => any) | null; 11 | // } 12 | 13 | // interface HTMLDivElement extends HTMLElement { 14 | // // addEventListener(type: K, listener: (this: HTMLDivElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; 15 | // addEventListener( 16 | // type: K, listener: (this: HTMLDivElement, ev: HTMLElementEventMap[K] extends MouseEvent ? MouseEvent & HTMLElementEventMap[K] : HTMLElementEventMap[K] 17 | // ) => any, options?: boolean | AddEventListenerOptions): void; 18 | // } 19 | 20 | 21 | // interface HTMLElement { 22 | // // addEventListener(type: K, listener: (this: HTMLDivElement, ev: HTMLElementEventMap[K]) => any, options?: boolean | AddEventListenerOptions): void; 23 | // addEventListener( 24 | // type: K, listener: (this: HTMLElement, ev: HTMLElementEventMap[K] extends MouseEvent ? MouseEvent & HTMLElementEventMap[K] : HTMLElementEventMap[K] 25 | // ) => any, options?: boolean | AddEventListenerOptions): void; 26 | // } -------------------------------------------------------------------------------- /sources/document/addEventListener.d.ts: -------------------------------------------------------------------------------- 1 | /** Automatically generated content: */ 2 | 3 | interface HTMLAnchorElement { 4 | addEventListener( 5 | type: K, listener: (this: HTMLAnchorElement, ev: HTMLElementEventMap[K] extends UIEvent ? UIEvent & HTMLElementEventMap[K] : HTMLElementEventMap[K] 6 | ) => any, options?: boolean | AddEventListenerOptions): void; 7 | } 8 | interface HTMLAreaElement { 9 | addEventListener( 10 | type: K, listener: (this: HTMLAreaElement, ev: HTMLElementEventMap[K] extends UIEvent ? UIEvent & HTMLElementEventMap[K] : HTMLElementEventMap[K] 11 | ) => any, options?: boolean | AddEventListenerOptions): void; 12 | } 13 | interface HTMLBRElement { 14 | addEventListener( 15 | type: K, listener: (this: HTMLBRElement, ev: HTMLElementEventMap[K] extends UIEvent ? UIEvent & HTMLElementEventMap[K] : HTMLElementEventMap[K] 16 | ) => any, options?: boolean | AddEventListenerOptions): void; 17 | } 18 | interface HTMLBaseElement { 19 | addEventListener( 20 | type: K, listener: (this: HTMLBaseElement, ev: HTMLElementEventMap[K] extends UIEvent ? UIEvent & HTMLElementEventMap[K] : HTMLElementEventMap[K] 21 | ) => any, options?: boolean | AddEventListenerOptions): void; 22 | } 23 | interface HTMLButtonElement { 24 | addEventListener( 25 | type: K, listener: (this: HTMLButtonElement, ev: HTMLElementEventMap[K] extends UIEvent ? UIEvent & HTMLElementEventMap[K] : HTMLElementEventMap[K] 26 | ) => any, options?: boolean | AddEventListenerOptions): void; 27 | } 28 | interface HTMLCanvasElement { 29 | addEventListener( 30 | type: K, listener: (this: HTMLCanvasElement, ev: HTMLElementEventMap[K] extends UIEvent ? UIEvent & HTMLElementEventMap[K] : HTMLElementEventMap[K] 31 | ) => any, options?: boolean | AddEventListenerOptions): void; 32 | } 33 | interface HTMLDListElement { 34 | addEventListener( 35 | type: K, listener: (this: HTMLDListElement, ev: HTMLElementEventMap[K] extends UIEvent ? UIEvent & HTMLElementEventMap[K] : HTMLElementEventMap[K] 36 | ) => any, options?: boolean | AddEventListenerOptions): void; 37 | } 38 | interface HTMLDataElement { 39 | addEventListener( 40 | type: K, listener: (this: HTMLDataElement, ev: HTMLElementEventMap[K] extends UIEvent ? UIEvent & HTMLElementEventMap[K] : HTMLElementEventMap[K] 41 | ) => any, options?: boolean | AddEventListenerOptions): void; 42 | } 43 | interface HTMLDataListElement { 44 | addEventListener( 45 | type: K, listener: (this: HTMLDataListElement, ev: HTMLElementEventMap[K] extends UIEvent ? UIEvent & HTMLElementEventMap[K] : HTMLElementEventMap[K] 46 | ) => any, options?: boolean | AddEventListenerOptions): void; 47 | } 48 | interface HTMLDetailsElement { 49 | addEventListener( 50 | type: K, listener: (this: HTMLDetailsElement, ev: HTMLElementEventMap[K] extends UIEvent ? UIEvent & HTMLElementEventMap[K] : HTMLElementEventMap[K] 51 | ) => any, options?: boolean | AddEventListenerOptions): void; 52 | } 53 | interface HTMLDialogElement { 54 | addEventListener( 55 | type: K, listener: (this: HTMLDialogElement, ev: HTMLElementEventMap[K] extends UIEvent ? UIEvent & HTMLElementEventMap[K] : HTMLElementEventMap[K] 56 | ) => any, options?: boolean | AddEventListenerOptions): void; 57 | } 58 | interface HTMLDirectoryElement { 59 | addEventListener( 60 | type: K, listener: (this: HTMLDirectoryElement, ev: HTMLElementEventMap[K] extends UIEvent ? UIEvent & HTMLElementEventMap[K] : HTMLElementEventMap[K] 61 | ) => any, options?: boolean | AddEventListenerOptions): void; 62 | } 63 | interface HTMLDivElement { 64 | addEventListener( 65 | type: K, listener: (this: HTMLDivElement, ev: HTMLElementEventMap[K] extends UIEvent ? UIEvent & HTMLElementEventMap[K] : HTMLElementEventMap[K] 66 | ) => any, options?: boolean | AddEventListenerOptions): void; 67 | } 68 | interface HTMLElement { 69 | addEventListener( 70 | type: K, listener: (this: HTMLElement, ev: HTMLElementEventMap[K] extends UIEvent ? UIEvent & HTMLElementEventMap[K] : HTMLElementEventMap[K] 71 | ) => any, options?: boolean | AddEventListenerOptions): void; 72 | } 73 | interface HTMLEmbedElement { 74 | addEventListener( 75 | type: K, listener: (this: HTMLEmbedElement, ev: HTMLElementEventMap[K] extends UIEvent ? UIEvent & HTMLElementEventMap[K] : HTMLElementEventMap[K] 76 | ) => any, options?: boolean | AddEventListenerOptions): void; 77 | } 78 | interface HTMLFieldSetElement { 79 | addEventListener( 80 | type: K, listener: (this: HTMLFieldSetElement, ev: HTMLElementEventMap[K] extends UIEvent ? UIEvent & HTMLElementEventMap[K] : HTMLElementEventMap[K] 81 | ) => any, options?: boolean | AddEventListenerOptions): void; 82 | } 83 | interface HTMLFontElement { 84 | addEventListener( 85 | type: K, listener: (this: HTMLFontElement, ev: HTMLElementEventMap[K] extends UIEvent ? UIEvent & HTMLElementEventMap[K] : HTMLElementEventMap[K] 86 | ) => any, options?: boolean | AddEventListenerOptions): void; 87 | } 88 | interface HTMLFormElement { 89 | addEventListener( 90 | type: K, listener: (this: HTMLFormElement, ev: HTMLElementEventMap[K] extends UIEvent ? UIEvent & HTMLElementEventMap[K] : HTMLElementEventMap[K] 91 | ) => any, options?: boolean | AddEventListenerOptions): void; 92 | } 93 | interface HTMLFrameElement { 94 | addEventListener( 95 | type: K, listener: (this: HTMLFrameElement, ev: HTMLElementEventMap[K] extends UIEvent ? UIEvent & HTMLElementEventMap[K] : HTMLElementEventMap[K] 96 | ) => any, options?: boolean | AddEventListenerOptions): void; 97 | } 98 | interface HTMLHRElement { 99 | addEventListener( 100 | type: K, listener: (this: HTMLHRElement, ev: HTMLElementEventMap[K] extends UIEvent ? UIEvent & HTMLElementEventMap[K] : HTMLElementEventMap[K] 101 | ) => any, options?: boolean | AddEventListenerOptions): void; 102 | } 103 | interface HTMLHeadElement { 104 | addEventListener( 105 | type: K, listener: (this: HTMLHeadElement, ev: HTMLElementEventMap[K] extends UIEvent ? UIEvent & HTMLElementEventMap[K] : HTMLElementEventMap[K] 106 | ) => any, options?: boolean | AddEventListenerOptions): void; 107 | } 108 | interface HTMLHeadingElement { 109 | addEventListener( 110 | type: K, listener: (this: HTMLHeadingElement, ev: HTMLElementEventMap[K] extends UIEvent ? UIEvent & HTMLElementEventMap[K] : HTMLElementEventMap[K] 111 | ) => any, options?: boolean | AddEventListenerOptions): void; 112 | } 113 | interface HTMLHtmlElement { 114 | addEventListener( 115 | type: K, listener: (this: HTMLHtmlElement, ev: HTMLElementEventMap[K] extends UIEvent ? UIEvent & HTMLElementEventMap[K] : HTMLElementEventMap[K] 116 | ) => any, options?: boolean | AddEventListenerOptions): void; 117 | } 118 | interface HTMLIFrameElement { 119 | addEventListener( 120 | type: K, listener: (this: HTMLIFrameElement, ev: HTMLElementEventMap[K] extends UIEvent ? UIEvent & HTMLElementEventMap[K] : HTMLElementEventMap[K] 121 | ) => any, options?: boolean | AddEventListenerOptions): void; 122 | } 123 | interface HTMLImageElement { 124 | addEventListener( 125 | type: K, listener: (this: HTMLImageElement, ev: HTMLElementEventMap[K] extends UIEvent ? UIEvent & HTMLElementEventMap[K] : HTMLElementEventMap[K] 126 | ) => any, options?: boolean | AddEventListenerOptions): void; 127 | } 128 | interface HTMLInputElement { 129 | addEventListener( 130 | type: K, listener: (this: HTMLInputElement, ev: HTMLElementEventMap[K] extends UIEvent ? UIEvent & HTMLElementEventMap[K] : HTMLElementEventMap[K] 131 | ) => any, options?: boolean | AddEventListenerOptions): void; 132 | } 133 | interface HTMLLIElement { 134 | addEventListener( 135 | type: K, listener: (this: HTMLLIElement, ev: HTMLElementEventMap[K] extends UIEvent ? UIEvent & HTMLElementEventMap[K] : HTMLElementEventMap[K] 136 | ) => any, options?: boolean | AddEventListenerOptions): void; 137 | } 138 | interface HTMLLabelElement { 139 | addEventListener( 140 | type: K, listener: (this: HTMLLabelElement, ev: HTMLElementEventMap[K] extends UIEvent ? UIEvent & HTMLElementEventMap[K] : HTMLElementEventMap[K] 141 | ) => any, options?: boolean | AddEventListenerOptions): void; 142 | } 143 | interface HTMLLegendElement { 144 | addEventListener( 145 | type: K, listener: (this: HTMLLegendElement, ev: HTMLElementEventMap[K] extends UIEvent ? UIEvent & HTMLElementEventMap[K] : HTMLElementEventMap[K] 146 | ) => any, options?: boolean | AddEventListenerOptions): void; 147 | } 148 | interface HTMLLinkElement { 149 | addEventListener( 150 | type: K, listener: (this: HTMLLinkElement, ev: HTMLElementEventMap[K] extends UIEvent ? UIEvent & HTMLElementEventMap[K] : HTMLElementEventMap[K] 151 | ) => any, options?: boolean | AddEventListenerOptions): void; 152 | } 153 | interface HTMLMapElement { 154 | addEventListener( 155 | type: K, listener: (this: HTMLMapElement, ev: HTMLElementEventMap[K] extends UIEvent ? UIEvent & HTMLElementEventMap[K] : HTMLElementEventMap[K] 156 | ) => any, options?: boolean | AddEventListenerOptions): void; 157 | } 158 | interface HTMLMarqueeElement { 159 | addEventListener( 160 | type: K, listener: (this: HTMLMarqueeElement, ev: HTMLElementEventMap[K] extends UIEvent ? UIEvent & HTMLElementEventMap[K] : HTMLElementEventMap[K] 161 | ) => any, options?: boolean | AddEventListenerOptions): void; 162 | } 163 | interface HTMLMenuElement { 164 | addEventListener( 165 | type: K, listener: (this: HTMLMenuElement, ev: HTMLElementEventMap[K] extends UIEvent ? UIEvent & HTMLElementEventMap[K] : HTMLElementEventMap[K] 166 | ) => any, options?: boolean | AddEventListenerOptions): void; 167 | } 168 | interface HTMLMetaElement { 169 | addEventListener( 170 | type: K, listener: (this: HTMLMetaElement, ev: HTMLElementEventMap[K] extends UIEvent ? UIEvent & HTMLElementEventMap[K] : HTMLElementEventMap[K] 171 | ) => any, options?: boolean | AddEventListenerOptions): void; 172 | } 173 | interface HTMLMeterElement { 174 | addEventListener( 175 | type: K, listener: (this: HTMLMeterElement, ev: HTMLElementEventMap[K] extends UIEvent ? UIEvent & HTMLElementEventMap[K] : HTMLElementEventMap[K] 176 | ) => any, options?: boolean | AddEventListenerOptions): void; 177 | } 178 | interface HTMLModElement { 179 | addEventListener( 180 | type: K, listener: (this: HTMLModElement, ev: HTMLElementEventMap[K] extends UIEvent ? UIEvent & HTMLElementEventMap[K] : HTMLElementEventMap[K] 181 | ) => any, options?: boolean | AddEventListenerOptions): void; 182 | } 183 | interface HTMLOListElement { 184 | addEventListener( 185 | type: K, listener: (this: HTMLOListElement, ev: HTMLElementEventMap[K] extends UIEvent ? UIEvent & HTMLElementEventMap[K] : HTMLElementEventMap[K] 186 | ) => any, options?: boolean | AddEventListenerOptions): void; 187 | } 188 | interface HTMLObjectElement { 189 | addEventListener( 190 | type: K, listener: (this: HTMLObjectElement, ev: HTMLElementEventMap[K] extends UIEvent ? UIEvent & HTMLElementEventMap[K] : HTMLElementEventMap[K] 191 | ) => any, options?: boolean | AddEventListenerOptions): void; 192 | } 193 | interface HTMLOptGroupElement { 194 | addEventListener( 195 | type: K, listener: (this: HTMLOptGroupElement, ev: HTMLElementEventMap[K] extends UIEvent ? UIEvent & HTMLElementEventMap[K] : HTMLElementEventMap[K] 196 | ) => any, options?: boolean | AddEventListenerOptions): void; 197 | } 198 | interface HTMLOptionElement { 199 | addEventListener( 200 | type: K, listener: (this: HTMLOptionElement, ev: HTMLElementEventMap[K] extends UIEvent ? UIEvent & HTMLElementEventMap[K] : HTMLElementEventMap[K] 201 | ) => any, options?: boolean | AddEventListenerOptions): void; 202 | } 203 | interface HTMLOutputElement { 204 | addEventListener( 205 | type: K, listener: (this: HTMLOutputElement, ev: HTMLElementEventMap[K] extends UIEvent ? UIEvent & HTMLElementEventMap[K] : HTMLElementEventMap[K] 206 | ) => any, options?: boolean | AddEventListenerOptions): void; 207 | } 208 | interface HTMLParagraphElement { 209 | addEventListener( 210 | type: K, listener: (this: HTMLParagraphElement, ev: HTMLElementEventMap[K] extends UIEvent ? UIEvent & HTMLElementEventMap[K] : HTMLElementEventMap[K] 211 | ) => any, options?: boolean | AddEventListenerOptions): void; 212 | } 213 | interface HTMLParamElement { 214 | addEventListener( 215 | type: K, listener: (this: HTMLParamElement, ev: HTMLElementEventMap[K] extends UIEvent ? UIEvent & HTMLElementEventMap[K] : HTMLElementEventMap[K] 216 | ) => any, options?: boolean | AddEventListenerOptions): void; 217 | } 218 | interface HTMLPictureElement { 219 | addEventListener( 220 | type: K, listener: (this: HTMLPictureElement, ev: HTMLElementEventMap[K] extends UIEvent ? UIEvent & HTMLElementEventMap[K] : HTMLElementEventMap[K] 221 | ) => any, options?: boolean | AddEventListenerOptions): void; 222 | } 223 | interface HTMLPreElement { 224 | addEventListener( 225 | type: K, listener: (this: HTMLPreElement, ev: HTMLElementEventMap[K] extends UIEvent ? UIEvent & HTMLElementEventMap[K] : HTMLElementEventMap[K] 226 | ) => any, options?: boolean | AddEventListenerOptions): void; 227 | } 228 | interface HTMLProgressElement { 229 | addEventListener( 230 | type: K, listener: (this: HTMLProgressElement, ev: HTMLElementEventMap[K] extends UIEvent ? UIEvent & HTMLElementEventMap[K] : HTMLElementEventMap[K] 231 | ) => any, options?: boolean | AddEventListenerOptions): void; 232 | } 233 | interface HTMLQuoteElement { 234 | addEventListener( 235 | type: K, listener: (this: HTMLQuoteElement, ev: HTMLElementEventMap[K] extends UIEvent ? UIEvent & HTMLElementEventMap[K] : HTMLElementEventMap[K] 236 | ) => any, options?: boolean | AddEventListenerOptions): void; 237 | } 238 | interface HTMLScriptElement { 239 | addEventListener( 240 | type: K, listener: (this: HTMLScriptElement, ev: HTMLElementEventMap[K] extends UIEvent ? UIEvent & HTMLElementEventMap[K] : HTMLElementEventMap[K] 241 | ) => any, options?: boolean | AddEventListenerOptions): void; 242 | } 243 | interface HTMLSelectElement { 244 | addEventListener( 245 | type: K, listener: (this: HTMLSelectElement, ev: HTMLElementEventMap[K] extends UIEvent ? UIEvent & HTMLElementEventMap[K] : HTMLElementEventMap[K] 246 | ) => any, options?: boolean | AddEventListenerOptions): void; 247 | } 248 | interface HTMLSlotElement { 249 | addEventListener( 250 | type: K, listener: (this: HTMLSlotElement, ev: HTMLElementEventMap[K] extends UIEvent ? UIEvent & HTMLElementEventMap[K] : HTMLElementEventMap[K] 251 | ) => any, options?: boolean | AddEventListenerOptions): void; 252 | } 253 | interface HTMLSourceElement { 254 | addEventListener( 255 | type: K, listener: (this: HTMLSourceElement, ev: HTMLElementEventMap[K] extends UIEvent ? UIEvent & HTMLElementEventMap[K] : HTMLElementEventMap[K] 256 | ) => any, options?: boolean | AddEventListenerOptions): void; 257 | } 258 | interface HTMLSpanElement { 259 | addEventListener( 260 | type: K, listener: (this: HTMLSpanElement, ev: HTMLElementEventMap[K] extends UIEvent ? UIEvent & HTMLElementEventMap[K] : HTMLElementEventMap[K] 261 | ) => any, options?: boolean | AddEventListenerOptions): void; 262 | } 263 | interface HTMLStyleElement { 264 | addEventListener( 265 | type: K, listener: (this: HTMLStyleElement, ev: HTMLElementEventMap[K] extends UIEvent ? UIEvent & HTMLElementEventMap[K] : HTMLElementEventMap[K] 266 | ) => any, options?: boolean | AddEventListenerOptions): void; 267 | } 268 | interface HTMLTableCaptionElement { 269 | addEventListener( 270 | type: K, listener: (this: HTMLTableCaptionElement, ev: HTMLElementEventMap[K] extends UIEvent ? UIEvent & HTMLElementEventMap[K] : HTMLElementEventMap[K] 271 | ) => any, options?: boolean | AddEventListenerOptions): void; 272 | } 273 | interface HTMLTableCellElement { 274 | addEventListener( 275 | type: K, listener: (this: HTMLTableCellElement, ev: HTMLElementEventMap[K] extends UIEvent ? UIEvent & HTMLElementEventMap[K] : HTMLElementEventMap[K] 276 | ) => any, options?: boolean | AddEventListenerOptions): void; 277 | } 278 | interface HTMLTableColElement { 279 | addEventListener( 280 | type: K, listener: (this: HTMLTableColElement, ev: HTMLElementEventMap[K] extends UIEvent ? UIEvent & HTMLElementEventMap[K] : HTMLElementEventMap[K] 281 | ) => any, options?: boolean | AddEventListenerOptions): void; 282 | } 283 | interface HTMLTableDataCellElement { 284 | addEventListener( 285 | type: K, listener: (this: HTMLTableDataCellElement, ev: HTMLElementEventMap[K] extends UIEvent ? UIEvent & HTMLElementEventMap[K] : HTMLElementEventMap[K] 286 | ) => any, options?: boolean | AddEventListenerOptions): void; 287 | } 288 | interface HTMLTableElement { 289 | addEventListener( 290 | type: K, listener: (this: HTMLTableElement, ev: HTMLElementEventMap[K] extends UIEvent ? UIEvent & HTMLElementEventMap[K] : HTMLElementEventMap[K] 291 | ) => any, options?: boolean | AddEventListenerOptions): void; 292 | } 293 | interface HTMLTableHeaderCellElement { 294 | addEventListener( 295 | type: K, listener: (this: HTMLTableHeaderCellElement, ev: HTMLElementEventMap[K] extends UIEvent ? UIEvent & HTMLElementEventMap[K] : HTMLElementEventMap[K] 296 | ) => any, options?: boolean | AddEventListenerOptions): void; 297 | } 298 | interface HTMLTableRowElement { 299 | addEventListener( 300 | type: K, listener: (this: HTMLTableRowElement, ev: HTMLElementEventMap[K] extends UIEvent ? UIEvent & HTMLElementEventMap[K] : HTMLElementEventMap[K] 301 | ) => any, options?: boolean | AddEventListenerOptions): void; 302 | } 303 | interface HTMLTableSectionElement { 304 | addEventListener( 305 | type: K, listener: (this: HTMLTableSectionElement, ev: HTMLElementEventMap[K] extends UIEvent ? UIEvent & HTMLElementEventMap[K] : HTMLElementEventMap[K] 306 | ) => any, options?: boolean | AddEventListenerOptions): void; 307 | } 308 | interface HTMLTemplateElement { 309 | addEventListener( 310 | type: K, listener: (this: HTMLTemplateElement, ev: HTMLElementEventMap[K] extends UIEvent ? UIEvent & HTMLElementEventMap[K] : HTMLElementEventMap[K] 311 | ) => any, options?: boolean | AddEventListenerOptions): void; 312 | } 313 | interface HTMLTextAreaElement { 314 | addEventListener( 315 | type: K, listener: (this: HTMLTextAreaElement, ev: HTMLElementEventMap[K] extends UIEvent ? UIEvent & HTMLElementEventMap[K] : HTMLElementEventMap[K] 316 | ) => any, options?: boolean | AddEventListenerOptions): void; 317 | } 318 | interface HTMLTimeElement { 319 | addEventListener( 320 | type: K, listener: (this: HTMLTimeElement, ev: HTMLElementEventMap[K] extends UIEvent ? UIEvent & HTMLElementEventMap[K] : HTMLElementEventMap[K] 321 | ) => any, options?: boolean | AddEventListenerOptions): void; 322 | } 323 | interface HTMLTitleElement { 324 | addEventListener( 325 | type: K, listener: (this: HTMLTitleElement, ev: HTMLElementEventMap[K] extends UIEvent ? UIEvent & HTMLElementEventMap[K] : HTMLElementEventMap[K] 326 | ) => any, options?: boolean | AddEventListenerOptions): void; 327 | } 328 | interface HTMLTrackElement { 329 | addEventListener( 330 | type: K, listener: (this: HTMLTrackElement, ev: HTMLElementEventMap[K] extends UIEvent ? UIEvent & HTMLElementEventMap[K] : HTMLElementEventMap[K] 331 | ) => any, options?: boolean | AddEventListenerOptions): void; 332 | } 333 | interface HTMLUListElement { 334 | addEventListener( 335 | type: K, listener: (this: HTMLUListElement, ev: HTMLElementEventMap[K] extends UIEvent ? UIEvent & HTMLElementEventMap[K] : HTMLElementEventMap[K] 336 | ) => any, options?: boolean | AddEventListenerOptions): void; 337 | } 338 | interface HTMLUnknownElement { 339 | addEventListener( 340 | type: K, listener: (this: HTMLUnknownElement, ev: HTMLElementEventMap[K] extends UIEvent ? UIEvent & HTMLElementEventMap[K] : HTMLElementEventMap[K] 341 | ) => any, options?: boolean | AddEventListenerOptions): void; 342 | } 343 | -------------------------------------------------------------------------------- /sources/document/cloneNode.d.ts: -------------------------------------------------------------------------------- 1 | interface HTMLElement{ 2 | cloneNode(deep?: boolean): HTMLElement; 3 | } 4 | -------------------------------------------------------------------------------- /sources/document/currentTarget.ts: -------------------------------------------------------------------------------- 1 | 2 | type Spread = { 3 | [K in keyof A | keyof B]: K extends keyof A & keyof B ? (A[K] | B[K]) : K extends keyof B ? B[K] : K extends keyof A ? A[K] : never; 4 | // [K in keyof A | keyof B]: K extends keyof A ? A[K] : (K extends keyof B ? B[K] : never) 5 | }; 6 | 7 | // // test Spread: 8 | // { 9 | // let a: Spread<{ a: 1 }, { a: '', b: 1 }> 10 | // } 11 | 12 | 13 | /// Events: 14 | 15 | interface UIEvent { 16 | // readonly target: (EventTarget extends T 17 | // ? EventTarget 18 | // : T extends Document 19 | // ? Document | Node 20 | // : T extends Window 21 | // ? Node 22 | // : Node) | null; 23 | 24 | readonly target: (EventTarget extends T 25 | ? EventTarget 26 | : T extends infer R extends Window | Document 27 | ? EventTarget extends G ? (R | Node) : G 28 | : Node) | null; 29 | // readonly target: (EventTarget extends T 30 | // ? EventTarget 31 | // : Node) | null; 32 | // readonly target: (EventTarget extends T 33 | // ? EventTarget 34 | // : Node extends T 35 | // ? Node 36 | // : Element) | null; 37 | // readonly target: (T extends Window ? Node : T) | null; 38 | readonly currentTarget: T | null; 39 | 40 | } 41 | 42 | 43 | type EventTargets = EventTarget | Node | Element | HTMLElement | SVGAElement | Document | Window; 44 | 45 | 46 | interface MouseEvent { 47 | // readonly target: (EventTarget extends T ? EventTarget : Node) | null; 48 | // readonly target: T extends Window ? T : UIEvent['target']; 49 | readonly target: (EventTarget extends G ? UIEvent['target'] : G) | null; 50 | readonly currentTarget: T | null; 51 | } 52 | 53 | 54 | interface KeyboardEvent { 55 | // readonly target: (EventTarget extends T ? EventTarget : Node) | null; 56 | // readonly target: UIEvent['target']; 57 | readonly target: (EventTarget extends G ? UIEvent['target'] : G) | null; 58 | readonly currentTarget: T | null; 59 | } 60 | 61 | interface FocusEvent { 62 | readonly currentTarget: T | null; 63 | } 64 | 65 | // type GenericEvent = (KeyboardEvent | MouseEvent) & UIEvent 66 | // type GenericEvent = (KeyboardEvent | MouseEvent) 67 | 68 | interface Document { 69 | addEventListener( 70 | type: K, 71 | listener: (this: Document, ev: DocumentEventMap[K] extends KeyboardEvent | MouseEvent ? DocumentEventMap[K] & UIEvent : DocumentEventMap[K]) => any, 72 | options?: boolean | AddEventListenerOptions): void; 73 | } 74 | 75 | 76 | 77 | interface Window { 78 | // onclick: ((this: GlobalEventHandlers, ev: Merge) => any) | null; 79 | addEventListener( 80 | type: K, 81 | listener: ( 82 | this: Window, 83 | // ev: WindowEventMap[K] extends KeyboardEvent | MouseEvent ? Merge> : WindowEventMap[K]) => any, 84 | 85 | ev: WindowEventMap[K] extends KeyboardEvent | MouseEvent 86 | ? (Merge> & { isTrusted: true }) 87 | | (Merge> & { isTrusted: false; }) 88 | : WindowEventMap[K]) => any, 89 | 90 | options?: boolean | AddEventListenerOptions): void; 91 | } 92 | 93 | 94 | interface HTMLTextAreaElement { 95 | addEventListener( 96 | type: 'input', 97 | listener: (this: HTMLTextAreaElement, ev: InputEvent & UIEvent & { target: HTMLTextAreaElement }) => any, 98 | options?: boolean | AddEventListenerOptions): void; 99 | 100 | addEventListener( 101 | type: 'focus', 102 | listener: ( 103 | this: HTMLTextAreaElement, 104 | ev: UIEvent & FocusEvent & { target: HTMLTextAreaElement }) => any, 105 | options?: boolean | AddEventListenerOptions): void; 106 | } 107 | 108 | interface HTMLInputElement { 109 | addEventListener( 110 | type: 'input', 111 | listener: ( 112 | this: HTMLInputElement, 113 | ev: HTMLElementEventMap['input'] & Partial> & { target: HTMLInputElement }) => any, 114 | options?: boolean | AddEventListenerOptions): void; 115 | 116 | addEventListener( 117 | type: 'focus', 118 | listener: ( 119 | this: HTMLInputElement, 120 | ev: UIEvent & FocusEvent & { target: HTMLInputElement }) => any, 121 | options?: boolean | AddEventListenerOptions): void; 122 | } -------------------------------------------------------------------------------- /sources/document/generators/.addEventListener.g.js: -------------------------------------------------------------------------------- 1 | //@ts-check 2 | 3 | const fs = require('fs'); 4 | const libdom = fs.readFileSync('node_modules/typescript/lib/lib.dom.d.ts').toString() 5 | const matches = libdom.matchAll(/addEventListener\(type: K, listener: \(this: (?\w+),[\s\S]+?\n/g) 6 | let acc = '' 7 | for (let match of matches) { 8 | const [declaration, name] = match; 9 | const newSign = 'HTMLElementEventMap[K] extends UIEvent ? UIEvent<' + name + '> & HTMLElementEventMap[K] : HTMLElementEventMap[K]'; 10 | const newDeclaration = `interface ${name} {\n\t${declaration.replace('HTMLElementEventMap[K]', newSign)}}\n`.replace( 11 | 'HTMLElementEventMap>(', 12 | 'HTMLElementEventMap>(\n\t\t' 13 | ).replace( 14 | '[K] : HTMLElementEventMap[K]', 15 | '[K] : HTMLElementEventMap[K]\n\t' 16 | ) 17 | acc += newDeclaration; 18 | } 19 | 20 | fs.writeFileSync('sources/document/addEventListener.d.ts', '/** Automatically generated content: */\n\n' + acc) -------------------------------------------------------------------------------- /sources/document/generators/.onEvent.g.js: -------------------------------------------------------------------------------- 1 | //@ts-check 2 | 3 | const fs = require('fs'); 4 | const libdom = fs.readFileSync('node_modules/typescript/lib/lib.dom.d.ts').toString() 5 | const matches = libdom.matchAll(/on\w+: \(\(this: GlobalEventHandlers, ev: (?MouseEvent|KeyboardEvent)\) => any\) \| null/g) 6 | 7 | let acc = '' 8 | for (let match of matches) { 9 | const [declaration, name] = match; 10 | const newDeclaration = declaration.replace(/ev: \w+/, `ev: ${name} & {currentTarget: Window | null}`) 11 | // const newDeclaration = declaration.replace(/ev: \w+/, `ev: Merge<${name}, {currentTarget: Window | null}>`) 12 | acc += '\t' + newDeclaration + '\n'; 13 | } 14 | 15 | acc = `interface Window {\n${acc}}` 16 | 17 | fs.writeFileSync('sources/document/onEvent.d.ts', '/** Automatically generated content: */\n\n' + acc) 18 | 19 | console.log('`onEvent` declarations generated...'); 20 | 21 | 22 | 23 | // Proposals: 24 | 25 | 26 | /// with TouchEvent: 27 | 28 | // const matches = libdom.matchAll(/on\w+(?:\?)?: \(\(this: GlobalEventHandlers, ev: (?MouseEvent|KeyboardEvent|TouchEvent)\) => any\) \| null/g) -------------------------------------------------------------------------------- /sources/document/onEvent.d.ts: -------------------------------------------------------------------------------- 1 | /** Automatically generated content: */ 2 | 3 | interface Window { 4 | // onkeydown: ((this: GlobalEventHandlers, ev: KeyboardEvent) => any) | null 5 | // onkeydown: ((this: GlobalEventHandlers, ev: KeyboardEvent & {currentTarget: Window | null}) => any) | null 6 | // onkeypress: ((this: GlobalEventHandlers, ev: KeyboardEvent & {currentTarget: Window | null}) => any) | null 7 | // onkeyup: ((this: GlobalEventHandlers, ev: KeyboardEvent & {currentTarget: Window | null}) => any) | null 8 | } 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /sources/document/querySelector.d.ts: -------------------------------------------------------------------------------- 1 | 2 | 3 | type HTMLTagNames = keyof HTMLElementTagNameMap; 4 | 5 | 6 | type HTMLSelector = S extends `${string},${string}` 7 | ? Element 8 | : S extends `${string}${` ` | `~`}${infer A extends string}` 9 | ? S extends (`${string}~${infer H extends HTMLTagNames}` | `${string} ${infer H extends HTMLTagNames}`) 10 | ? HTMLElementTagNameMap[H] 11 | : A extends `${string}${` ` | `]`}${string}` 12 | ? Element 13 | : A extends (`${infer H extends HTMLTagNames}${`.` | `#`}${string}`) 14 | ? HTMLElementTagNameMap[H] 15 | : Element 16 | : S extends (`${infer H extends HTMLTagNames}${`.` | `#`}${string}`) | (`${string}${`>` | `+`}${infer H extends HTMLTagNames}`) 17 | ? HTMLElementTagNameMap[H] 18 | : S extends (`${string}${`>` | `+`}${infer H extends HTMLTagNames}${`.` | `#`}${string}`) 19 | ? HTMLElementTagNameMap[H] 20 | : Element 21 | 22 | 23 | interface ParentNode { 24 | /** Returns the first element that is a descendant of node that matches selectors. */ 25 | querySelector(selectors: K): HTMLElementTagNameMap[K] | null; 26 | querySelector(selectors: K): SVGElementTagNameMap[K] | null; 27 | // /** @deprecated */ 28 | querySelector(selectors: K): HTMLElementDeprecatedTagNameMap[K] | null; 29 | querySelector(selector: S): HTMLSelector | null 30 | 31 | /** Returns all element descendants of node that match selectors. */ 32 | 33 | querySelectorAll(selectors: K): NodeListOf; 34 | querySelectorAll(selectors: K): NodeListOf; 35 | /** @deprecated */ 36 | querySelectorAll(selectors: K): NodeListOf; 37 | querySelectorAll(selector: S): NodeListOf> | null; 38 | 39 | // querySelector(selectors: string): E; 40 | // querySelectorAll(selectors: string): NodeListOf; 41 | 42 | 43 | /// drop because of ^5.0.0 required: 44 | 45 | // querySelector(selectors: K): MathMLElementTagNameMap[K] | null; 46 | // querySelectorAll(selectors: K): NodeListOf; 47 | } 48 | 49 | 50 | -------------------------------------------------------------------------------- /sources/ecmascript/Array/_index.ts: -------------------------------------------------------------------------------- 1 | /// 2 | /// 3 | 4 | 5 | -------------------------------------------------------------------------------- /sources/ecmascript/Array/indexof.d.ts: -------------------------------------------------------------------------------- 1 | type WidenLiteral = T extends string ? string : (T extends number ? number : T); 2 | type Indexes = Exclude["length"], T["length"]>; 3 | 4 | interface ReadonlyArray { 5 | // indexOf(searchElement: K extends true ? T : K extends 'any' ? WidenLiteral : never, fromIndex?: number): number 6 | // indexOf(this: ReadonlyArray, searchElement: K extends never ? T : K extends WidenLiteral ? WidenLiteral : never, fromIndex?: number): number 7 | indexOf(this: ReadonlyArray, searchElement: K extends never ? T : K extends WidenLiteral ? WidenLiteral : never, fromIndex?: number): number 8 | } 9 | 10 | // var index = (a as [number, number, number]).indexOf(44) -------------------------------------------------------------------------------- /sources/ecmascript/Array/isarray.d.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * @link https://github.com/microsoft/TypeScript/issues/17002#issuecomment-313719111 3 | */ 4 | interface ArrayConstructor { 5 | isArray(arg: any): arg is ReadonlyArray 6 | } 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /sources/ecmascript/Array/map.d.ts: -------------------------------------------------------------------------------- 1 | type ConstraitArray = A['length'] extends N ? A : ConstraitArray 2 | 3 | interface ReadonlyArray { 4 | readonly length: number, 5 | map(callbackfn: (this: readonly T[], value: T, index: number, array: readonly T[]) => U, thisArg?: any): ConstraitArray; 6 | } -------------------------------------------------------------------------------- /sources/ecmascript/index.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | /// 3 | -------------------------------------------------------------------------------- /sources/ecmascript/object/_index.ts: -------------------------------------------------------------------------------- 1 | /// 2 | /// 3 | /// 4 | /// 5 | /// 6 | // 7 | -------------------------------------------------------------------------------- /sources/ecmascript/object/create.ts: -------------------------------------------------------------------------------- 1 | interface ObjectConstructor { 2 | create(o: object | null): object; 3 | create(o: object | null, properties: PropertyDescriptorMap & ThisType): object; 4 | 5 | 6 | // create(o: T): T extends Object ? Object : object; - doesn't work as expected 7 | } -------------------------------------------------------------------------------- /sources/ecmascript/object/defineProperties.ts: -------------------------------------------------------------------------------- 1 | 2 | type PropertiesMapType>, F extends string> = { 3 | [K in keyof T]: T[K][F] extends (...args: any) => any ? ReturnType : T[K][F] 4 | } 5 | 6 | type ReadonlyMapType>, F extends string> = { 7 | readonly [K in keyof T]: T[K][F] extends (...args: any) => any ? ReturnType : T[K][F] 8 | } 9 | 10 | type MapType>, F extends string, R extends string> = 11 | { 12 | readonly [K in keyof T as T[K][R] extends false ? K : never]: T[K][F] 13 | } & { 14 | [K in keyof T as T[K][R] extends true ? K : never]: T[K][F] 15 | } 16 | 17 | 18 | /// MapType test: 19 | 20 | // { 21 | // type VS = { 22 | // a: { 23 | // value: number, 24 | // writable: false 25 | // }, 26 | // b: { 27 | // value: string, 28 | // writable: true, 29 | // } 30 | // } 31 | 32 | // function func1(yyy: MapType) { 33 | // yyy.b = '' 34 | // yyy.a = 1 35 | // } 36 | // } 37 | 38 | 39 | 40 | interface ObjectConstructor { 41 | // defineProperties(o: T, properties: PropertyDescriptorMap & ThisType): T; 42 | defineProperties>(o: T, attributes: A & ThisType): Merge< 43 | T, 44 | MapType 45 | >; 46 | defineProperties>(o: T, attributes: A & ThisType): Merge< 47 | T, 48 | ReadonlyMapType 49 | >; 50 | defineProperties>(o: T, attributes: A & ThisType): Merge< 51 | T, 52 | PropertiesMapType 53 | > 54 | defineProperties>(o: T, attributes: A & ThisType): Merge< 55 | T, 56 | ReadonlyMapType 57 | > 58 | } 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | // type WidenType = T extends string 68 | // ? string 69 | // : T extends number 70 | // ? number 71 | // : T extends boolean 72 | // ? boolean 73 | // : T extends null 74 | // ? object 75 | // : T extends undefined 76 | // ? unknown 77 | // : T 78 | 79 | 80 | 81 | -------------------------------------------------------------------------------- /sources/ecmascript/object/defineProperty.d.ts: -------------------------------------------------------------------------------- 1 | interface ObjectConstructor { 2 | // defineProperty(o: T, p: PropertyKey, attributes: PropertyDescriptor & ThisType): T; 3 | /** 4 | * @issue https://github.com/microsoft/TypeScript/issues/42919 5 | */ 6 | defineProperty(o: T, p: K, attributes: GenericPropertyDesc & ThisType): Merge< 7 | T, 8 | W extends true ? { [k in K]: V } : { readonly [k in K]: V } 9 | >; 10 | } 11 | 12 | interface GenericPropertyDesc extends PropertyDescriptor { 13 | configurable?: boolean; 14 | enumerable?: boolean; // enumerable: true; 15 | value?: V; 16 | writable?: W; 17 | get?(): V; 18 | set?(v: V): void; 19 | } 20 | 21 | 22 | // type WidenType = T extends string 23 | // ? string 24 | // : T extends number 25 | // ? number 26 | // : T extends boolean 27 | // ? boolean 28 | // : T extends null 29 | // ? object 30 | // : T extends undefined 31 | // ? unknown 32 | // : T 33 | 34 | 35 | 36 | -------------------------------------------------------------------------------- /sources/ecmascript/object/objectAssign.d.ts: -------------------------------------------------------------------------------- 1 | type Merge = Omit & K; 2 | 3 | type MergeAll, L extends never[] = [], Result extends {} = {}> = T['length'] extends infer N extends L['length'] 4 | ? Result 5 | : MergeAll> 6 | 7 | 8 | interface ObjectConstructor { 9 | /** 10 | * Copy the values of all of the enumerable own properties from one or more source objects to a 11 | * target object. Returns the target object. 12 | * @param target The target object to copy to. 13 | * @param source The source object from which to copy properties. 14 | */ 15 | assign(target: T, source: U): Merge; 16 | 17 | /** 18 | * Copy the values of all of the enumerable own properties from one or more source objects to a 19 | * target object. Returns the target object. 20 | * @param target The target object to copy to. 21 | * @param source1 The first source object from which to copy properties. 22 | * @param source2 The second source object from which to copy properties. 23 | */ 24 | assign(target: T, source1: U, source2: V): MergeAll<[T, U, V]>; 25 | 26 | /** 27 | * Copy the values of all of the enumerable own properties from one or more source objects to a 28 | * target object. Returns the target object. 29 | * @param target The target object to copy to. 30 | * @param source1 The first source object from which to copy properties. 31 | * @param source2 The second source object from which to copy properties. 32 | * @param source3 The third source object from which to copy properties. 33 | */ 34 | assign(target: T, source1: U, source2: V, source3: W): MergeAll<[T, U, V, W]>; 35 | 36 | /** 37 | * Copy the values of all of the enumerable own properties from one or more source objects to a 38 | * target object. Returns the target object. 39 | * @param target The target object to copy to. 40 | * @param sources One or more source objects from which to copy properties 41 | */ 42 | assign(target: object, ...sources: object[]): object 43 | 44 | } 45 | 46 | 47 | 48 | -------------------------------------------------------------------------------- /sources/ecmascript/object/objectKeys.ts: -------------------------------------------------------------------------------- 1 | // interface ObjectConstructor { 2 | // /** 3 | // * Returns the names of the enumerable string properties and methods of an object. 4 | // * @param o Object that contains the properties and methods. This can be an object that you created or an existing Document Object Model (DOM) object. 5 | // */ 6 | // // keys(o: T): Array & string[]; 7 | 8 | // getOwnPropertyNames(o: T): T extends Required ? Array : string[]; 9 | 10 | // keys(o: T): T extends Required ? Array : string[]; 11 | // entries(o: T): Array<[keyof T, T[keyof T]]>; 12 | // } 13 | 14 | 15 | // type A = { 16 | // a?: string, 17 | // b: number 18 | // } 19 | // let aa: A = { 20 | // a: '', 21 | // b: 1 22 | // } 23 | // const rr = Object.keys(aa) 24 | -------------------------------------------------------------------------------- /sources/ecmascript/object/setPrototypeOf.ts: -------------------------------------------------------------------------------- 1 | /// How necessary is this feature? 2 | 3 | interface ObjectConstructor { 4 | // getPrototypeOf(o: object): object | null; 5 | setPrototypeOf(o: T, proto: P): P extends object ? Merge : T; 6 | 7 | 8 | // setPrototypeOf(o: T, proto: P): P extends object ? T & P : T; 9 | } 10 | 11 | -------------------------------------------------------------------------------- /sources/index.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | /// 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /sources/utils/$research.ts: -------------------------------------------------------------------------------- 1 | /// Lifehack book: 2 | 3 | import { Overlap, Common, Diff } from "."; 4 | 5 | 6 | 7 | { 8 | /** 9 | * @think Its great but too easy and useless 10 | * @declineReason - too easy and useless 11 | * 12 | * @cat Array (Tuple) 13 | * @link https://gist.github.com/khalidx/6a4f949346df30a655b02207383b566a 14 | * @also https://stackoverflow.com/a/64034671/9659573 15 | * @param {[type,type1,type2,...]} A 16 | * @param {type} V 17 | * @description Excludes from tuple (!) specified type 18 | * @returns {[type,type1,type2,...]} 19 | * @example Filter<[string, number], number> => [string] 20 | */ 21 | type ExcludeFrom, V> = Exclude[] 22 | 23 | type F = ExcludeFrom, number> 24 | } 25 | 26 | 27 | { 28 | /// Optional Tuple 29 | 30 | type RemoveFirstFromTuple = 31 | T['length'] extends 0 ? undefined : 32 | (((...b: T) => void) extends (a: any, ...b: infer I) => void ? I : []) 33 | 34 | type Tail = T extends [infer A, ...infer R] ? R : never; 35 | 36 | 37 | type OptionalTuple = T['length'] extends 0 38 | ? R | A 39 | : OptionalTuple extends any[] ? RemoveFirstFromTuple : [], [...A, T[0]], A['length'] extends 0 ? never : (A | R)> 40 | 41 | { 42 | type A = [1, 2, 3] 43 | type POP = OptionalTuple 44 | let t1: POP = [1] 45 | let t2: POP = [1, 2] 46 | let t3: POP = [1, 2, 3] 47 | } 48 | 49 | // declined now because the same behavior could got in fact OUT OF THE BOX (!) by one line: 50 | 51 | { 52 | type F = (a: 1, b?: 2, c?: 3) => void 53 | type POP1 = Parameters 54 | let t1: POP1 = [1] 55 | let t2: POP1 = [1, 2] 56 | let t3: POP1 = [1, 2, 3] 57 | 58 | // type OPtionalTuple 59 | } 60 | 61 | // or 62 | 63 | { 64 | type A = [a: 1, b?: 2, c?: 3] 65 | } 66 | 67 | /** 68 | * @declineReason : 69 | * Thus, the benefit of this type is probably only to make a non-optional tuple optional, since there may be difficulties with this. 70 | * But this is such a rare case that I doubt it will be much in demand from the community. Therefore, I do not see it useful to add it to the package (at least for now) 71 | */ 72 | } 73 | 74 | 75 | 76 | { 77 | type ABC = 'A' | 'B' | 'C' 78 | type Num = '1' | '2' | '3' 79 | 80 | /** 81 | * @description like OptionalExceptOne, but for unions 82 | * @thoughts like OptionalExceptOne, but for unions 83 | */ 84 | type OptionalExceptOneOf = { 85 | [K in TT]: Exclude extends never 86 | ? Result // | { [k in K]: string } & { [k in TT & keyof Result]?: string } 87 | : OptionalExceptOneOf, EE, Result | { [k in K]: EE } & { [k in TT & keyof Result]?: EE }> 88 | }[TT] 89 | 90 | type II = OptionalExceptOneOf & OptionalExceptOneOf 91 | let t: II = { 92 | A: 1, 93 | 1: '' 94 | } 95 | 96 | /** 97 | * @declineReason - it seems too similar to OptionalExceptOne and too useless for accompared with it 98 | */ 99 | } 100 | 101 | 102 | 103 | 104 | 105 | /// GroupBy 106 | 107 | { 108 | type RemoveFirstFromTuple_ | any[]> = 109 | T['length'] extends 0 ? [] : 110 | (((...b: T) => void) extends (a: any, ...b: infer I) => void ? I : []) 111 | 112 | /** 113 | * @cat Object 114 | * @param {object[]} objects 115 | * @param {key} keyof $arg[number] 116 | * @description combines objects union into one with types union. Works like Combine, but just for union 117 | * @returns {{a: A | B, b: A | BarProp, ...}} 118 | * @example GroupBy<[{a: 'a1', b: '1'}, {a: 'a2', b: '2'}], 'a'> => [{a1: {b: '1'}}, {a2: {b: '2'}}] 119 | */ 120 | type GroupBy = T['length'] extends 0 121 | ? R 122 | : GroupBy, Key, [...R, { 123 | [_K in O[Key]as O[Key] extends PropertyKey ? O[Key] : never]: { 124 | [K in keyof O as K extends Key ? never : K]: O[K] 125 | } 126 | }]> 127 | 128 | type Ar = [{ a: 1, b: string }, { a: 2, c: boolean }]; 129 | type R = GroupBy 130 | 131 | /** 132 | * @declineReason - too similar to ReduceBy. To be honest it's it. 133 | */ 134 | } 135 | 136 | 137 | 138 | { 139 | /** 140 | * @declineReason - too easy to implement it 141 | * @description - add autohinting to optional union string 142 | */ 143 | type SmartString = keys | string & {} 144 | let a: SmartString<'aaa' | 'abb'> = 'aaa' 145 | let a1: SmartString<'aaa' | 'abb'> = 'aaa1' 146 | } 147 | 148 | 149 | 150 | { 151 | /// Common keys: 152 | type UU = { a: 1 } | { a: 2, b: 2 } 153 | type CommonKeys = keyof T; // => 'a' 154 | /** 155 | * @declineReason - too easy to implement it 156 | */ 157 | } 158 | 159 | 160 | 161 | { 162 | ///@names: PickByKey (DiscrimeBy|ExcludeExceptWithKeys) 163 | 164 | 165 | type FirstOrLast_ = (U extends any ? (x: () => U) => void : never) extends (x: infer P) => void // PropertyKey|object 166 | ? P extends () => infer Return ? Return : never 167 | : never; 168 | 169 | /** 170 | * @altname DiscrimeBy 171 | */ 172 | type PickByKey, R extends object = never, U extends O = FirstOrLast_> 173 | = Exclude extends never 174 | ? key extends keyof U ? R | U : R 175 | : PickByKey, key, key extends keyof U ? R | U : R> 176 | 177 | // https://www.typescriptlang.org/play?ssl=40&ssc=43&pln=38&pc=1#code/C4TwDgpgBAwg9gWwXAdgHgIIBooCEB8UAvFAN4CwAUFDVANoDSUAlilANYQhwBmUGUAGQcuvPAF0AXP0bioAHzyyqAXypUIADzBwATsCihIUACLMePNABUoW4BBQATAM5Q4AIwBWEAMbAcJraa9k6uHt5+hCQU1LSMLGyc3Hw2AIauTHYOLiLJplAA-FAoEABuELpQ0gxSUFbKlGqUVAD0LXUA8iYdULoOqQjQwHBQALIVAOYQVEbQAMpgfamOmEEhOeG+-nhr2WFeW1Gm5pa4OBiEwmYWmDgEQrCIyOjYePjqlLNQAGLMus7ADqWKxHGxZUL0Vg8Co-HAAOgRUJhACU5EVvlVimUKjNwNBkRBkOVfv9gNZdhDUigQHRxKCKTk6EjKt94YiUNDKqjClBkZiSuVdLjjN8MSQSQCgWg6ABGLAAJiwAGY6R8vgSiRAJcBvrpEFYAK5gAA2EAA+uTwTkCctUMaQBhdLpUiA0FSQIRFO7aUcqLQ6nQAOSmlATYAAC0DcitrgADDzaVUqABIAAU6YRcPc0isAEpiIRSnBmI58zGoKnUtJ3Wys9JmVAAJL5oiF4uOHmNzG03NqvE-P6S3QAGXSwAtAFUGfsIsAjqmp+X3TzU5ppKmW4QJ5uoEWS-zsboy8E9hW1wlOVAAAo7veOP20IpX6cVncNgnAA26NhFD9ftjSAKOKxDQgGHgA3P6fYioOgIjmOjaWIuJ4Qpsfg4EkL5XnqkD6CADBcPOyHrK4y5FKu647tuBa7u2B6CseJFnvWHIwjeNF3g+NBPi+G40e+ECft+PJ-sJYGClx9EVJBtAfG0UBTAYPhPKguSuDweoIG4Bx+DRHz6c0lBaDo+iGP24y6FMlooRsOnbJkNkzocxBQB0CDMGSVgYaIfAMJcUAMJB8mtr0-SDIYIwLEsHbuIJ9hCoZ0HQB0grGi6aA9OWaHbHyWV2S5pAqDgxGnj04qwR08EAhaHT4EcACimg+MaBqOBAGXFYQ5ZAZUklFFFEDLGgyKdZJ0gpRUaWuo1zWte1HSdTgA1DSNUATnVcntMZegGF8FlWWCjnabOOAOUx2VHG5HnWN5eR+Q8gWtO0XyNs4E4oMwqDWEcdBWNGR10I2KDxc4WzvZ96AgmiUA8Kkxqg5iwC6Aa0yfP2ZjOD4ujMIMuCuplR3ZbdL5JGIE26FNGX4DguWE-lJA9cVL5lQOpKVaO1VUw1TUtW1HVrV1R09VAfW5CTPlrSJCiS9IyJjccmPY7j0083N-PrbdxPlqTfBTr+0tTrL7yJWjxjk1NeMZS+RNi9rEvm+ltU09b9NkEVkvliz2rs2ONV1S5M28-NnUvsLouYXbeR61Ay0rKt62YnLIGYg7ICW4HasLQLmu20dOuS-1iyDXHIdGyLJvyTKUAALSualLpPVA8o11AzgAO6pGAYyTNAVIdrHjdKi3ADiepGnjSVrVO0RVlAMoqNLpCz4qUDZk3C+KKQa8ynKUCONIADsTTCtAowubHaBL9I884FfTc4Gv8oqP5hWT4EJAY1jOMQJbE4TjggZ3CBkIB8U0Bh975GiJJZeWBJKP1UJPIGIMwYfS+gnEgC4XxkQrOwaQ1EQp3ikkeXiqZcEXhhM2Di7Z8xFC7OJYCk8CSOAND4H+rpDrnTsrSU6XBxZ5HqCgA0CBYq6HEM7cshUCpFUkq5F2s4XL1FjGIgKIAICuBIPnWqCigwhjDJGf6TF4wyMfLyYxoFeQQGYawy2Go4DElgrqfURpTQWhBDwkAzthAxH9D4uIZomCsFcowLgch0hBIIiAAxp5sJwFwqACJPIOjBMiUQ2o3jfEZJoPEQJmioBhLOqeBJRRhbVFqEkmoZifFNEyc-SejoXJ0DvrvNeAJsahndnfFePhpDuDgHAU0VIVDiHAifa8z4SCOjoII4RFQ5BQHksacw0BwypB8OwGGehHhIFQBE1wqYAAsuZpD5zoJmV4mZcDiCmUIkR4hGEuSYSwthmBdAANSMAqAQA 178 | 179 | type UU = { a: 1 } | { a: 2, bb: 2 } | { bb: 11, d: 7 } | { bb1: 11, d1: 7 } 180 | type D = PickByKey 181 | let d: D = { 182 | a: 2, 183 | bb: 2 184 | } 185 | 186 | /** 187 | * @think - I think useful, but there is some error of infinity deep. At the same time in sandbox it work fine 188 | * @trouble - fixed by 'intersect' option 189 | * 190 | */ 191 | 192 | type U = { a: 1 } | { a: 2, bb: 2 } | { bb: 11, d: 7 } 193 | 194 | function func(u: U) { 195 | if ('a' in u) { 196 | let a: number = u.a; 197 | //@ts-expect-error 198 | let v: number = u.bb; 199 | } 200 | } 201 | 202 | /** 203 | * @think - the same behavior like guard => useless 204 | * 205 | */ 206 | 207 | } -------------------------------------------------------------------------------- /sources/utils/README.md: -------------------------------------------------------------------------------- 1 |
2 | 3 | ## Utility types: 4 | 5 |
6 |

Table of content

7 | 8 | 9 | #### Arrays: 10 | - [KeysArray](#keysarraykeys) 11 | - [ConstrainedArray](#constrainedarraynumber-type) 12 | - [Sequence](#sequencenumber) 13 | - [WideArray](#widearraytuple) 14 | - [ConvertTupleType](#converttupletypetuple) 15 | - [ArrayFilter](#arrayfilterunknown-type) 16 | - [MapArray](#maparrayunknown-key) 17 | - [ReduceBy](#ReduceByO-K) 18 | 19 | #### Objects: 20 | 21 | - [NonNullableKey](#nonnullablekeytype) 22 | - [OmitNullable](#omitnullabletype) 23 | - [Merge](#mergetype-type) 24 | - [MergeAll](#mergealltypes) 25 | - KeysMatching 26 | - [MapType](#maptypeobject-key) 27 | - [IntersectUnions](#intersectunionsu) 28 | - [IsUnion](#isuniont) 29 | - [Common](#commontype-type) 30 | - [Diff](#difftype-type) 31 | - [OptionalExceptOne](#optionalexceptoneobject) 32 | - [ObjectLength](#objectlengthtype) 33 | - [Join](#jointupleofobjects) 34 | - [OneOf](#oneofo) 35 | - [ReplaceTypes](#replacetypes) 36 | 37 | #### Unions: 38 | 39 | - Enumerate 40 | - [Overlap](#OverlapO) 41 | 42 |
43 | 44 | 45 | 46 | 47 | 48 | ### [KeysArray\](https://github.com/Sanshain/types-spring/blob/master/sources/utils/index.ts#L14) 49 | 50 | Creates tuple like array type from an object type: 51 | 52 | ```ts 53 | type ObjType = { 54 | a: string; 55 | b: string; 56 | c: string; 57 | }; 58 | 59 | const bar: KeysArray = ["d"]; // expected error => Type "d" is not assignable to type "a" | "b" | "c" 60 | 61 | const foo: KeysArray = [ // expected success 62 | "a", "b", "c" 63 | ]; 64 | ``` 65 | 66 |
67 | Constraits 68 | 69 | - *This is a rather complex recursive type and is designed directly for objects containing a little number of fields in order to maintain high performance of typescript server (no more than six are recommended)* 70 |
71 | 72 | ### [OmitNullable\](https://github.com/Sanshain/types-spring/blob/master/sources/utils/index.ts#L39) 73 | 74 | ```ts 75 | type User = { 76 | name: string; 77 | email: string | null; 78 | }; 79 | 80 | type NonNullableUserPropertyKeys = OmitNullable; // {name: string} 81 | ``` 82 | 83 | ### [NonNullableKey\](https://github.com/Sanshain/types-spring/blob/master/sources/utils/index.ts#L23) 84 | 85 | Extracts required keys from object: 86 | 87 | ```ts 88 | type User = { 89 | name: string; 90 | name2: string; 91 | email: string | null; 92 | email2?: string; 93 | }; 94 | 95 | let a: NonNullableKey = 'name' // 'name' | 'name2' 96 | ``` 97 | 98 | ### [ParseInt\](https://github.com/Sanshain/types-spring/blob/master/sources/utils/index.ts#L54) 99 | 100 | Extracts number from string 101 | 102 | ```ts 103 | type N = ParseInt<'7'> // type N = 7 104 | ``` 105 | 106 | ### [ConstrainedArray\](https://github.com/Sanshain/types-spring/blob/master/sources/utils/index.ts#L69) 107 | 108 | Generates fixed length array with specified type 109 | 110 | ```ts 111 | export let names: ConstrainedArray<2, boolean> = [false, true] // [boolean, boolean] 112 | ``` 113 | 114 | ### [Indexes\](https://github.com/Sanshain/types-spring/blob/master/sources/utils/index.ts#L86) 115 | 116 | Extract indexes from tuple like keyof object 117 | 118 | ```ts 119 | export const testArray = [ 120 | "test1", 121 | "test2", 122 | "test3", 123 | "test4" 124 | ] as const; 125 | 126 | type ArrayIndex = Indexes; // 0 | 1 | 2 | 3 127 | ``` 128 | 129 | ### [Sequence\](https://github.com/Sanshain/types-spring/blob/master/sources/utils/index.ts#L101) 130 | 131 | generates a tuple of the specified length as a sequence of numbers from 0: 132 | 133 | ```ts 134 | let re: Sequence<3> // [0, 1, 2] 135 | ``` 136 | 137 | ### [Merge\](https://github.com/Sanshain/types-spring/blob/master/sources/utils/index.ts#L124) 138 | 139 | Merges fields from two types like js spread or flow types spread 140 | 141 | ```ts 142 | type A = { 143 | a: string, 144 | b: number 145 | } 146 | type B = { 147 | b: string, 148 | c: number 149 | } 150 | 151 | type C = Merge 152 | let c: C; // {a: string, b: string, c: number} 153 | ``` 154 | 155 | ### [MergeAll\<[...Types]\>](https://github.com/Sanshain/types-spring/blob/master/sources/utils/index.ts#L135) 156 | 157 | Merges fields from unlimited amount of types like js spread or flow types spread 158 | 159 | ```ts 160 | type A = { 161 | a: string, 162 | b: number 163 | } 164 | type B = { 165 | b: string, 166 | c: number 167 | } 168 | 169 | type C = MergeAll<[A, B, { d: 7 }]> 170 | let c: C; // {a: string, b: string, c: number, d: 7} 171 | ``` 172 | 173 | ### [WideArray\](https://github.com/Sanshain/types-spring/blob/master/sources/utils/index.ts#L168) 174 | 175 | Converts types of the tuple to corresponding common type 176 | 177 | ```ts 178 | const arr = [1, 2, 3] as const // type is [1, 2, 3] 179 | type R = WideArray // type is [number, number, number] 180 | ``` 181 | 182 | ### [ConvertTupleType\](https://github.com/Sanshain/types-spring/blob/master/sources/utils/index.ts#L183) 183 | 184 | Converts types of the tuple to specified type 185 | 186 | ```ts 187 | const arr = [1, 2, 3] as const // type is [1, 2, 3] 188 | type R = ConvertTupleType 189 | let r: R; // type is [number, number, number] 190 | ``` 191 | 192 | ### [ArrayFilter](https://github.com/Sanshain/types-spring/blob/master/sources/utils/index.ts#L239) 193 | 194 | Excludes from array all types except Type 195 | 196 | ```ts 197 | const _a = [1, 2, '']; // (string | number)[] 198 | let rt: ArrayFilter // string[] 199 | ``` 200 | 201 | ### [MapArray](https://github.com/Sanshain/types-spring/blob/master/sources/utils/index.ts#L253) 202 | 203 | Map array item (object) to reduced object from specified key 204 | 205 | ```ts 206 | type A = [ 207 | { a: number, b: string }, 208 | { a: string, c: boolean } 209 | ] 210 | 211 | type R = MapArray // [number, string] 212 | ``` 213 | 214 | 215 | ### [MapType](https://github.com/Sanshain/types-spring/blob/master/sources/utils/index.ts#LL267C13-L267C21) 216 | 217 | Map object item (object) to reduced object from specified key 218 | 219 | ```ts 220 | type O = { 221 | a: { value: number, }, 222 | b: { value: string, } 223 | } 224 | 225 | let yyy: MapTypeValue // {a: number, b: number} 226 | ``` 227 | 228 | ### IntersectUnions\ 229 | 230 | Converts union to intersection 231 | 232 | ```ts 233 | let a: IntersectUnions<{ a: 1 } | { b: 1 }> = { a: 1, b: 1 } 234 | ``` 235 | 236 | ### IsUnion\ 237 | 238 | Detects whether the type is union 239 | 240 | ```ts 241 | let a: IsUnion = true 242 | let b: IsUnion = false 243 | ``` 244 | 245 | ### [Common\](https://github.com/Sanshain/types-spring/blob/master/sources/utils/index.ts#L307) 246 | 247 | Highlights common properties 248 | 249 | ```ts 250 | type A = { a: number, b: number, c: number } 251 | type B = { aa: number, b: number, c: string } 252 | let c: Common // {b: number, c: number | string} 253 | ``` 254 | 255 | ### Diff\ 256 | 257 | returns an object with properties of the first type that are not present in the second 258 | 259 | ```ts 260 | type A = { a: number, b: number, c: number } 261 | type B = { b: number, c: string } 262 | let c: Diff // {a: number} 263 | ``` 264 | 265 | ### [OptionalExceptOne\](https://github.com/Sanshain/types-spring/blob/master/sources/utils/index.ts#L333) 266 | 267 | Makes all fields optional, except for any one of them. So at least one of them should be declared: 268 | 269 | ```ts 270 | type O = OptionalExceptOne<{a: 1, b: 1, c: 1}> 271 | let o: O = {} // type error! 272 | let oa: O = {a: 1} // success 273 | ``` 274 | 275 | ### [ObjectLength\](https://github.com/Sanshain/types-spring/blob/master/sources/utils/index.ts#367) 276 | 277 | Counts the number of keys in an object 278 | 279 | ```ts 280 | type Obj = { 281 | id: number; 282 | id_user: string; 283 | is_active: boolean; 284 | }; 285 | let objectLengt: ObjectLength // 3 286 | ``` 287 | 288 | ### [Join\](https://github.com/Sanshain/types-spring/blob/master/sources/utils/index.ts#L386) 289 | 290 | Counts the number of keys in an object 291 | 292 | ```ts 293 | type A = [{a: number}, {c: number}, {d: string}] 294 | type O = Join
295 | const o: O = { a: 1, c: 3, d: ''} 296 | ``` 297 | 298 | ### [ReplaceTypes](https://github.com/Sanshain/types-spring/blob/master/sources/utils/index.ts#L394) 299 | 300 | Replaces type S of object type fields to type R (recursivly!): 301 | 302 | ```ts 303 | type Profile = { 304 | s: string, 305 | b: boolean, 306 | c: { f: string } 307 | } 308 | 309 | // for example replacing of `string` to `number`: 310 | 311 | let rrr: ReplaceTypes = { 312 | s: 1, // type string => number 313 | b: false, // type boolean remained the same 314 | c: {f: 3} // type string => number 315 | } 316 | ``` 317 | 318 | ### [OneOf\](https://github.com/Sanshain/types-spring/blob/master/sources/utils/index.ts#L419) 319 | 320 | Makes all fields as optional expect either one. 321 | 322 | ```ts 323 | type Params = { 324 | a: 1, 325 | b: 1, 326 | c: 1 327 | } 328 | 329 | let a: OneOf = {a: 1} 330 | let b: OneOf = {b: 1} 331 | //@ts-expect-error 332 | let ab: OneOf = {a: 1, b: 1} 333 | //@ts-expect-error 334 | let abc: OneOf = {a: 1, b: 1, c: 1} 335 | ``` 336 | 337 | 338 | ### [Overlap\](https://github.com/Sanshain/types-spring/blob/master/sources/utils/index.ts#L449) 339 | 340 | Combines objects union into one. It works like Merge type, but gets objects not from different arguments, but from a single union of objects passed as an single argument. 341 | The essential difference is that fields of the result object are not overwritten, but they are union of appropriate field types 342 | 343 | ```ts 344 | 345 | type AA = { a: number, b: number } | { b: string, c: string } 346 | type O = Overlap // => { a: number, b: number | string, c: string } 347 | let o: O = { a: 1, b: 1, c: '' } 348 | let os: O = { a: 1, b: '', c: '' } 349 | 350 | ``` 351 | 352 | ### [ReduceBy\](https://github.com/Sanshain/types-spring/blob/master/sources/utils/index.ts#467) 353 | 354 | Reduce objects array by specidied key to object. For example we have an constant array and wants to reduce it by `a` field: 355 | 356 | #### Before: 357 | 358 | ```ts 359 | const ar = [{ a: 'a1', b: number }, { a: 'a2', c: string }] as const 360 | const r = ar.reduce((acc, a) => ({ [a.a]: a, ...acc }), {}) 361 | // `o` has type `{}` 362 | ``` 363 | 364 | #### After: 365 | 366 | ```ts 367 | const r = ar.reduce((acc, a) => ({ [a.a]: a, ...acc }), {}) as ReduceBy 368 | // now the `o` has type `{a1: { a: 'a1', b: number }, a2: { a: 'a2', c: string }}` 369 | ``` 370 | 371 | 372 |
373 |
374 |
375 | 376 | 377 | ## Table of contents as table: 378 | 379 | |Arrays|Objects|Unions| 380 | |------|-------|------| 381 | |[KeysArray](#keysarraykeys)|[Merge](#mergetype-type)|Enumerate|ParseInt| 382 | |[ConstrainedArray](#constrainedarraynumber-type)|[MergeAll](#mergealltypes)|Ranged|| 383 | |[Sequence](#sequencenumber)|[Diff](#diff)|[Overlap](#OverlapO)|| 384 | |[WideArray](#widearraytuple)|[Common](#common)||| 385 | |[ConvertTupleType](#converttupletypetuple)|[OmitNullable](#omitnullabletype)||| 386 | |[ArrayFilter](#arrayfilterunknown-type)|[NonNullableKey](#nonnullablekeytype)||| 387 | |[MapArray](#maparrayunknown-key)|[MapType](#maptypeobject-key)||| 388 | |[ReduceBy](#ReduceByO)|[IsUnion](#isuniont)||| 389 | ||[IntersectUnions](#intersectunionsu)||| 390 | ||KeysMatching||| 391 | ||[OptionalExceptOne](#optionalexceptoneobject)||| 392 | ||[ObjectLength](#objectlengthtype)||| 393 | 394 |
395 | 396 |

Pseudocode:

397 | 398 | - [KeysArray:](#keysarraykeys) `a|b|c` => `[a, b, c]` 399 | - [NonNullableKey:](https://github.com/Sanshain/types-spring/tree/master/sources/utils#nonnullablekeytype) `{k0?, k1, k2}` => `k2 | k2` 400 | - [OmitNullable:](https://github.com/Sanshain/types-spring/tree/master/sources/utils#omitnullabletype) `{k0?, k1, k2}` => `{k2, k2}` 401 | - [ConvertTupleType:](https://github.com/Sanshain/types-spring/tree/master/sources/utils#constraitarraynumber-type) `` => `tuple` 402 | - [Indexes:](https://github.com/Sanshain/types-spring/tree/master/sources/utils#indexesconst-array) `` => `keyof tuple` 403 | - [Sequence](https://github.com/Sanshain/types-spring/tree/master/sources/utils#sequencenumber) `` => `tuple` 404 | - [Merge:](https://github.com/Sanshain/types-spring/tree/master/sources/utils#mergetype-type) `` => `{...A, ...B}` 405 | - [MergeAll:](https://github.com/Sanshain/types-spring/tree/master/sources/utils#mergealltypes) `<[A, B, C]>` => `{...A, ...B, ...C}` 406 | - [ArrayFilter](https://github.com/Sanshain/types-spring/tree/master/sources/utils#arrayfilterunknown-type) `<(A|B|C)[], A>` => `(B|C)[]` 407 | - [MapArray:](https://github.com/Sanshain/types-spring/tree/master/sources/utils#maparrayunknown-key) `[{value: number}]` => `[number]` 408 | - [MapType:](https://github.com/Sanshain/types-spring/tree/master/sources/utils#maptypeobject-key) `{a: {value: number}}` => `{a: number}` 409 | - [Overlap:](https://github.com/Sanshain/types-spring/tree/master/sources/utils#overlapo) `{a: 1} | {a: 2, b: 2}` => `{a: 1 | 2, b: 2}` 410 | 411 |
412 | -------------------------------------------------------------------------------- /sources/utils/index.ts: -------------------------------------------------------------------------------- 1 | // https://stackoverflow.com/questions/69676439/create-constant-array-type-from-an-object-type 2 | type _KeysArray = { 3 | [Key in keyof Dict]: Exclude extends never ? [...Result, Key] : _KeysArray, [...Result, Key]>; 4 | }[keyof Dict]; 5 | 6 | type KeysArray__Error = `Object with too much (${N}) fields amount (expected less than ${L}) passed to KeysArray type` 7 | /** 8 | * @cat Array 9 | * @param { a | b | c | ... } FieldKeys 10 | * @attention is not recommended for objects with more than 6 keys due to the severity of calculations 11 | * @returns {[a, b, ...]} 12 | * @alt_names ArrayOfKeys|KeysAsTuple 13 | * @cat Object 14 | * @example KeysArray< {a,b,c} > = ['a', 'b', 'c'] 15 | */ 16 | export type KeysArray = 7> = ObjectLength extends Enumerate ? _KeysArray : KeysArray__Error> 17 | 18 | 19 | /** 20 | * @cat Object 21 | * @description Extracts required keys from object 22 | * @param {a, b: |null, c, ...} T 23 | * @returns {a | c | ...} 24 | * @example {a?: any, b: any, c: any} => b | c 25 | */ 26 | export type NonNullableKey = { 27 | [P in keyof T]: null extends T[P] ? never : undefined extends T[P] ? never : P 28 | }[keyof T]; 29 | 30 | 31 | 32 | /** 33 | * @cat Object 34 | * @description Omit nullable types from object 35 | * @param {a, b, c?, ...} T 36 | * @returns {{a, b, ...} 37 | * @example {a?: any, b: any, c: any} => {b: any, c: any} 38 | */ 39 | export type OmitNullable = { 40 | [K in keyof T as null extends T[K] ? never : K]: T[K]; 41 | } 42 | 43 | 44 | 45 | 46 | /** 47 | * @cat primitives 48 | * @requires ^4.7.4 49 | * @description converts number string to number (usefull inside another types) 50 | * @param {`${number}`} 51 | * @returns {number} 52 | * @example type N = ParseInt<'7'> 53 | */ 54 | export type _ParseInt = T extends `${infer N extends number}` ? N : never; 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | /** 63 | * @cat Array (Tuple) 64 | * @param {number} 65 | * @description Generates fixed length array with specified type 66 | * @returns {[type, type, ...]} 67 | * @example {ConstraitArray<2, boolean> => [false, true]} 68 | */ 69 | export type ConstrainedArray = A['length'] extends N ? A : ConstrainedArray 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | /** 80 | * @cat Array (Tuple) 81 | * @param {any[]} 82 | * @description Extract indexes from tuple like keyof object 83 | * @returns {0 | 1 | 2 | ...} 84 | * @example Indexes<['a', 'b', 'a']> => 0 | 1 | 2 85 | */ 86 | export type Indexes = Exclude["length"], T["length"]> 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | /** 95 | * @cat Array (Tuple) 96 | * @param {number} L 97 | * @description Generates a tuple with the specified length as a sequence of numbers 98 | * @returns [0, 1, 2, ...] 99 | * @example Sequence<3> => [0, 1, 2] 100 | */ 101 | export type Sequence = A['length'] extends L ? A : Sequence 102 | 103 | 104 | 105 | 106 | 107 | 108 | // /** 109 | // * @deprecated reminder for alternative way of the Merge<> 110 | // */ 111 | // type Merge = { 112 | // // [K in keyof A | keyof B]: K extends keyof A & keyof B ? (A[K] | B[K]) : K extends keyof B ? B[K] : K extends keyof A ? A[K] : never; 113 | // [K in keyof A | keyof B]: K extends keyof A ? A[K] : (K extends keyof B ? B[K] : never) 114 | // }; 115 | 116 | /** 117 | * @cat Object 118 | * @description like flow type spread 119 | * @param {object} T 120 | * @param {object} O 121 | * @returns {{...T, ...O}} - like flow type spread 122 | * @example Merge<{a: number, b: number}, {b: string, c: string}> => {a: number, b: string, c: string} 123 | */ 124 | export type Merge = _O extends 'override' 125 | ? {[K in keyof T | keyof O]: K extends keyof O ? O[K] : K extends keyof T ? T[K] : never } // Omit & K 126 | : _Combine_ 127 | 128 | /** 129 | * @cat Object 130 | * @description Merges fields from unlimited amount of types like js spread or flow types spread 131 | * @param {[...Types]} 132 | * @returns {{...Types}} - like flow type spread 133 | * @example MergeAll<[{a: number}, {b: string}, { b: 7 }]> => {a: number, b: 7} 134 | */ 135 | export type MergeAll, L extends never[] = [], Result extends {} = {}> = T['length'] extends infer N extends L['length'] 136 | ? Result 137 | : MergeAll> // : MergeAll & T[L['length']]> 138 | 139 | 140 | 141 | 142 | type _WidenType = T extends string 143 | ? string 144 | : T extends number 145 | ? number 146 | : T extends boolean 147 | ? boolean 148 | : T extends null 149 | ? object 150 | : T extends undefined 151 | ? unknown 152 | : T 153 | 154 | // export type WideArray
, R extends unknown[] = []> = A['length'] extends R['length'] 155 | // ? R 156 | // : WideArray]>; 157 | 158 | 159 | /** 160 | * @cat Array (Tuple) 161 | * @description Converts types of the tuple to corresponding common type 162 | * @param {[Tuple]} 163 | * @returns {[Tuple]} 164 | * @example [1, 2, 3] => [number, number, number] 165 | */ 166 | export type WideArray> = { 167 | // [K in keyof A]: A[K] extends string ? string : (A[K] extends number ? number : A[K]) 168 | [K in keyof A]: _WidenType 169 | } 170 | 171 | 172 | 173 | /** 174 | * @cat Array (Tuple) 175 | * @description Converts types of the tuple to specified type 176 | * @param {[Tuple]} A 177 | * @param {type} T 178 | * @returns {[Tuple]} 179 | * @example ConvertTupleType<[1, 2, 3], string> => [string, string, string] 180 | */ 181 | export type ConvertTupleType, T> = { 182 | [K in keyof A]: T 183 | } 184 | 185 | 186 | 187 | 188 | 189 | 190 | 191 | /** 192 | * @cat union 193 | * @atention not recomended for sequences over more then one hundren elements 194 | * @link https://stackoverflow.com/a/70307091/9659573 195 | * @param {number} N 196 | * @description Generates union keys with the specified length as a sequence of numbers 197 | * @returns {0 | 1 | 2 | ...} 198 | * @example Enumerate<3> => 0 | 1 | 2 199 | */ 200 | export type Enumerate = Acc['length'] extends N 201 | ? Acc[number] 202 | : Enumerate 203 | 204 | 205 | 206 | export type Ranged = Exclude, Enumerate> 207 | 208 | 209 | 210 | 211 | 212 | 213 | /** 214 | * @cat Object 215 | * @alternative type KeysWithValsOfType = keyof { [ P in keyof T as T[P] extends V ? P : never ] : P }; 216 | * @link https://stackoverflow.com/a/66144780/9659573 217 | * @param {Record} T 218 | * @param {unknown} V 219 | * @description Extract keys with specified value type from object T 220 | * @returns {key1 | key2 | ...} 221 | * @example KeysMatching<{a: 1, b: '', c: string}, string> => b | c 222 | */ 223 | export type KeysMatching = { [K in keyof T]-?: T[K] extends V ? K : never }[keyof T]; 224 | 225 | 226 | 227 | 228 | 229 | /** 230 | * @cat Array 231 | * @param {(type|type1|type2|...)[]} A 232 | * @param {type} V 233 | * @description Excludes from array all types except V 234 | * @returns {(type)[]} 235 | * @example ArrayFilter, number> => Array 236 | */ 237 | export type ArrayFilter, V> = Array 238 | 239 | 240 | 241 | 242 | 243 | /** 244 | * @cat Object 245 | * @param {{a: A, b: A}} T 246 | * @param {string} F 247 | * @description maps object to object 248 | * @returns {{a: A[F], b: A[F]}} 249 | * @example MapType<{a: {a: string}}, "a"> => {a: string} 250 | */ 251 | export type MapType>, F extends string> = { 252 | [K in keyof T]: T[K][F] 253 | } 254 | 255 | 256 | 257 | /** 258 | * @cat Array & Tuple 259 | * @param {[A,A]} T 260 | * @param {string} F 261 | * @description map array item (object) to reduced object from specified key 262 | * @returns {[A[F], A[F]]} 263 | * @example MapType<[{a: string}], "a"> => [string] 264 | */ 265 | export type MapArray[] | ReadonlyArray>, F extends string> = { 266 | [K in keyof T]: T[K][F] 267 | } 268 | 269 | 270 | 271 | 272 | 273 | /** 274 | * @cat Object 275 | * @param {{a} | {b}}} U 276 | * @description convert union to intersection 277 | * @link https://stackoverflow.com/a/50375286 278 | * @returns {{a} & {b}} 279 | * @example IntersectUnion<{a:1} | {b:1}> => {a: 1} & {b: 1} 280 | */ 281 | export type IntersectUnion = (U extends any ? (k: U) => void : never) extends ((k: infer I) => void) ? I : never 282 | 283 | 284 | /** 285 | * @cat Object 286 | * @param {{a} | {b}}} U 287 | * @description detects whether the type is union 288 | * @notes {boolean is always true} 289 | * @link https://stackoverflow.com/a/53955431 290 | * @returns {boolean} 291 | * @example IsUnion<{a:1} | {b:1}> => true 292 | */ 293 | export type IsUnion = [T] extends [IntersectUnion] ? false : true 294 | 295 | 296 | 297 | /** 298 | * @cat Object 299 | * @description highlights common properties 300 | * @link https://stackoverflow.com/questions/47375916/typescript-how-to-create-type-with-common-properties-of-two-types 301 | * @example Common<{ a: 1 }, { a: 2, b: 1 }> => {a: 1 | 2} 302 | */ 303 | export type Common = { 304 | [K in keyof A & keyof B]: A[K] | B[K] 305 | } 306 | 307 | 308 | /** 309 | * @cat Object 310 | * @param {T} minuend 311 | * @param {D} subtrahend 312 | * @description returns an object with properties of the first type that are not present in the second 313 | * @return {object} - object with properties of the first type that are not present in the second 314 | */ 315 | export type Diff = { 316 | [K in keyof T as K extends keyof D ? never : K]: T[K] 317 | } 318 | 319 | 320 | 321 | 322 | 323 | type _OptionalExceptOne = { 324 | [K in keyof T]: Exclude extends never // [K] extends [keyof Rest] 325 | ? _OptionalExceptOne, Rest | K, Result | Partial> & { [k in K]: T[K] }> 326 | : Result 327 | }[keyof T] 328 | 329 | /** 330 | * @cat Object 331 | * @attention tested on more then 20 fields (on purpose to check level of deep to calculatioan) 332 | * @param {T} object 333 | * @description makes all fields are optional excepts one of them 334 | */ 335 | export type OptionalExceptOne = _OptionalExceptOne 336 | 337 | 338 | 339 | declare const __brand: unique symbol 340 | /** 341 | * @protected - popular type 342 | * @description branded type 343 | */ 344 | export type ScreenType = T & { readonly [__brand]?: B } 345 | 346 | 347 | 348 | /** 349 | * @requires ^4.2.3 350 | * @cat union 351 | * @description Extract last or first type from union type 352 | * @TODO rename to {PopFrom} 353 | */ 354 | type FirstOrLast_ = (U extends any ? (x: () => U) => void : never) extends (x: infer P) => void // PropertyKey|object 355 | ? P extends () => infer Return ? Return : never 356 | : never; 357 | 358 | 359 | 360 | /** 361 | * @cat Object 362 | * @requires ^4.2.3 363 | * @param {O} object 364 | * @description counts the number of keys in an object 365 | * @return {number} 366 | * @example {a,b,c} => 3 367 | */ 368 | export type ObjectLength> = [L] extends [never] 369 | ? Res['length'] 370 | : ObjectLength, [L, ...Res]>; 371 | 372 | 373 | /** 374 | * @cat Object | Array 375 | * @param {O} object 376 | * @param {*} S replaced type 377 | * @param {*} R new type 378 | * @description deep replace all fields with specified type S to type R in object O 379 | * @return {object} 380 | * @example ['', '', 5], string, 0 => [0, 0, 5] 381 | */ 382 | export type ReplaceTypes = { 383 | [K in keyof O]: O[K] extends object 384 | ? ReplaceTypes 385 | : O[K] extends S ? Exclude | R : O[K] 386 | } 387 | 388 | 389 | /** @alt `T extends [infer F, ...infer R] ? R : never` - @Altdeclined - for some reason returns `unknown` instead of pure `T` type */ 390 | type RemoveFirstFromTuple_ | any[]> = 391 | T['length'] extends 0 ? [] : 392 | (((...b: T) => void) extends (a: any, ...b: infer I) => void ? I : []) 393 | 394 | 395 | /** 396 | * @cat Object 397 | * @param {AO} Tuple 398 | * @description convert tuple of objects to overall object 399 | * @return {object} 400 | * @example [{a}, {b}, {c}] => {a, b, c} 401 | */ 402 | export type Join = T extends [infer F, ...infer R] 403 | ? F & Join 404 | : {} 405 | // export type Join, R extends object = {}> = AO['length'] extends 0 406 | // ? R 407 | // : Join, R & AO[0]> 408 | 409 | 410 | 411 | 412 | /** 413 | * @cat Object 414 | * @param {T} object 415 | * @description makes just one of the fields [is] available 416 | * @return {Union} 417 | * @example {a, b} => {a, b: never} | {a: never, b} 418 | */ 419 | export type OneOf = { 420 | [K in keyof T]: {[k in K]: T[K]} & {[k in keyof Omit]?: never} 421 | } [keyof T] 422 | 423 | 424 | /** 425 | * @cat Object 426 | * @param {A} object 427 | * @param {B} object 428 | * @param {M} [__CombineMethod] - approach to apply the utility (via 'intersect' or 'union': sometimes for service work it's important) 429 | * @description combines two objects into one with types union (like merge, but with fields union) 430 | * @returns {{...A | ...B}} 431 | * @example Combine<{a: number, b: number}, {b: string, c: string}> => {a: number, b: number | string, c: string}* 432 | * @alternativeRealization type Combine = Diff & Diff & Common 433 | * @internalCause - useless on the back of Overlap and Merge (: don't bother expirience with unnecessary types) 434 | */ 435 | type _Combine_ = M extends 'union' ? { 436 | [K in keyof A | keyof B]: K extends keyof A & keyof B ? (A[K] | B[K]) : K extends keyof B ? B[K] : K extends keyof A ? A[K] : never; 437 | // [K in keyof A | keyof B]: K extends keyof A ? A[K] : (K extends keyof B ? B[K] : never) 438 | } : Diff & Diff & Common 439 | 440 | 441 | /** 442 | * @cat Object 443 | * @param {A|B|...} objects 444 | * @param {M} [__CombineMethod] - approach to apply the utility (via 'intersect' or 'union': sometimes for service work it's important) 445 | * @description combines objects union into one with types union. Works like Combine, but just for union 446 | * @returns {{a: A | B, b: A | BarProp, ...}} 447 | * @example Overlay<{a: number, b: number}|{b: string, c: string}> => {a: number, b: number | string, c: string} 448 | */ 449 | export type Overlap> = Exclude extends never 450 | ? _Combine_ 451 | : Overlap, __M, _Combine_> 452 | 453 | 454 | /** 455 | * @description merge intersection of objects to solid single object 456 | */ 457 | type _Simplify_ = {[K in keyof T]: T[K]} & {} 458 | 459 | /** 460 | * @cat Object 461 | * @param {object[]} objects 462 | * @param {key} keyof $arg[number] 463 | * @description reduce objects array by specidied key to object 464 | * @returns {{a: A | B, b: A | BarProp, ...}} 465 | * @example ReduceBy<[{a: 'a1', b: '1'}, {a: 'a2', b: '2'}], 'a'> => {a1: {b: '1', ...}, a2: {b: '2', ...}} 466 | */ 467 | export type ReduceBy, Key extends keyof T[number], R extends {} = {}, 468 | O extends object = T[0]> = T['length'] extends 0 469 | ? _Simplify_ 470 | : ReduceBy, Key, R & { 471 | [_K in O[Key] as O[Key] extends PropertyKey ? O[Key] : never]: { 472 | // [K in keyof O as K extends Key ? never : K]: O[K] 473 | [K in keyof O]: O[K] 474 | } 475 | }> 476 | 477 | 478 | 479 | 480 | 481 | /** 482 | * @category {Object} 483 | * @param {PropertyKey} Keys 484 | * @param {object} O 485 | * @description set optinal props of O passed as first arg 486 | * @returns {object} conditionally partial object 487 | * @example Optional<'a'|'b', {a: 1, b:1, c: 1}> => {a: 1 | undefined, b:1 | undefined, c: 1} 488 | */ 489 | export type Optional = _Simplify_<{ 490 | [K in keyof O as K extends Keys ? K : never]?: O[K] } & { 491 | [K in keyof O as K extends Keys ? never : K]: O[K] 492 | }> 493 | 494 | 495 | /** 496 | * @category {Object} 497 | * @param {PropertyKey} Keys 498 | * @param {object} O 499 | * @description set optional props of O except passed as first arg 500 | * @returns {object} conditionally partial object 501 | * @example Optional<'a'|'b', {a: 1, b:1, c: 1}> => {a: 1, b:1, c: 1 | undefined} 502 | */ 503 | export type OptionalExcept = _Simplify_<{ 504 | [K in keyof O as K extends Keys ? K : never]: O[K] } & { 505 | [K in keyof O as K extends Keys ? never : K]?: O[K] 506 | }> 507 | 508 | 509 | 510 | // /** 511 | // * @cat Object 512 | // * @param {Union} UNION 513 | // * @param {key} keyof $arg[number] 514 | // * @description exclude from union all objects without specified discriminant key 515 | // * @returns {{A | B | C | ...}} 516 | // * @example PickByKey<{ a: 1 } | { a: 2, bb: 2 } | { bb: 11, d: 7 }, 'a'> => { a: 1 } | { a: 2, bb: 2 }} 517 | // */ 518 | // export type PickByKey, R extends object = never, U extends O = FirstOrLast_> 519 | // = Exclude extends never 520 | // ? key extends keyof U ? R | U : R 521 | // : PickByKey, key, key extends keyof U ? R | U : R> 522 | 523 | 524 | 525 | 526 | /// TYPES ALIASES: 527 | 528 | export type Spread = Merge; 529 | 530 | 531 | /// INTERNAL ADDITIONAL TYPES: 532 | 533 | type __CombineMethod = 'intersect' | 'union'; 534 | 535 | 536 | //@see also: 537 | // https://stackoverflow.com/questions/62084836/what-does-it-mean-for-a-type-to-distribute-over-unions 538 | 539 | 540 | -------------------------------------------------------------------------------- /test-utility-types/.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "typescript.tsdk": "node_modules\\typescript\\lib" 3 | } -------------------------------------------------------------------------------- /test-utility-types/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "test-utility-types", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "keywords": [], 10 | "author": "", 11 | "license": "ISC", 12 | "dependencies": { 13 | "ts-toolbelt": "^9.6.0", 14 | "type-fest": "^4.10.2", 15 | "types-spring": "1.1.4", 16 | "utility-types": "^3.10.0" 17 | }, 18 | "devDependencies": { 19 | "typescript": "^5.3.3" 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /test-utility-types/pnpm-lock.yaml: -------------------------------------------------------------------------------- 1 | lockfileVersion: 5.3 2 | 3 | specifiers: 4 | ts-toolbelt: ^9.6.0 5 | type-fest: ^4.10.2 6 | types-spring: 1.1.4 7 | typescript: ^5.3.3 8 | utility-types: ^3.10.0 9 | 10 | dependencies: 11 | ts-toolbelt: 9.6.0 12 | type-fest: 4.10.2 13 | types-spring: 1.1.4_typescript@5.3.3 14 | utility-types: 3.10.0 15 | 16 | devDependencies: 17 | typescript: 5.3.3 18 | 19 | packages: 20 | 21 | /ts-toolbelt/9.6.0: 22 | resolution: {integrity: sha512-nsZd8ZeNUzukXPlJmTBwUAuABDe/9qtVDelJeT/qW0ow3ZS3BsQJtNkan1802aM9Uf68/Y8ljw86Hu0h5IUW3w==} 23 | dev: false 24 | 25 | /type-fest/4.10.2: 26 | resolution: {integrity: sha512-anpAG63wSpdEbLwOqH8L84urkL6PiVIov3EMmgIhhThevh9aiMQov+6Btx0wldNcvm4wV+e2/Rt1QdDwKHFbHw==} 27 | engines: {node: '>=16'} 28 | dev: false 29 | 30 | /types-spring/1.1.4_typescript@5.3.3: 31 | resolution: {integrity: sha512-J0TE3T5kLVMbBNfaiHK52p4G1KeStIz9bguRKgIxFAsihD8YFxa6iq2cLgMZcAdoy0Zwsqc2WBLR7sNoy3O5yQ==} 32 | peerDependencies: 33 | typescript: ^4.7.4 || ^5.0.4 34 | dependencies: 35 | typescript: 5.3.3 36 | dev: false 37 | 38 | /typescript/5.3.3: 39 | resolution: {integrity: sha512-pXWcraxM0uxAS+tN0AG/BF2TyqmHO014Z070UsJ+pFvYuRSq8KH8DmWpnbXe0pEPDHXZV3FcAbJkijJ5oNEnWw==} 40 | engines: {node: '>=14.17'} 41 | hasBin: true 42 | 43 | /utility-types/3.10.0: 44 | resolution: {integrity: sha512-O11mqxmi7wMKCo6HKFt5AhO4BwY3VV68YU07tgxfz8zJTIxr4BpsezN49Ffwy9j3ZpwwJp4fkRwjRzq3uWE6Rg==} 45 | engines: {node: '>= 4'} 46 | dev: false 47 | -------------------------------------------------------------------------------- /test-utility-types/sources/ecma.ts: -------------------------------------------------------------------------------- 1 | window.addEventListener('load', function(event) { 2 | const elem = this.document.querySelector('input'); 3 | elem?.addEventListener('click', event => { 4 | console.log(event.target?.textContent); 5 | }) 6 | }) -------------------------------------------------------------------------------- /test-utility-types/sources/index.ts: -------------------------------------------------------------------------------- 1 | import { FixedLengthArray } from "type-fest" 2 | import { TaggedUnion } from "type-fest" 3 | // import { Merge } from "type-fest" 4 | import { ListOf } from "ts-toolbelt/out/Object/ListOf" 5 | import { Either, ExcludeKeys, Intersect, IntersectKeys, Replace } from "ts-toolbelt/out/Object/_api" 6 | import { Merge } from "ts-toolbelt/out/Object/_api" 7 | // import { Filter } from "ts-toolbelt/out/Object/Filter"; 8 | import { Group } from "ts-toolbelt/out/List/Group"; 9 | import { Zip } from "ts-toolbelt/out/List/Zip"; 10 | import { Extract } from "ts-toolbelt/out/List/Extract"; 11 | import { Take } from "ts-toolbelt/out/List/Take"; 12 | import { Filter } from "ts-toolbelt/out/List/Filter"; // !! ts-toolbelt have very perplexing types for understanding, insufficiently documented web-site and modest readme 13 | import { Flatten } from "ts-toolbelt/out/List/Flatten"; 14 | import { Compulsory } from "ts-toolbelt/out/Object/Compulsory"; 15 | 16 | import type { InvariantOf, Opaque } from 'type-fest'; 17 | import { SharedUnionFieldsDeep, OptionalKeysOf } from 'type-fest'; 18 | import type { MultidimensionalArray } from 'type-fest'; 19 | import { Common } from "types-spring" 20 | import { RequireExactlyOne } from "type-fest" 21 | import { MergeDeep } from "type-fest" 22 | import { BuiltIn } from "ts-toolbelt/out/Misc/_api" 23 | import { ReadonlyDeep } from "type-fest" 24 | import { Assign, DeepReadonly, Intersection } from "utility-types" 25 | import { O } from 'ts-toolbelt' 26 | import { PickDeep } from "type-fest" 27 | 28 | 29 | // import type { SharedUnionFieldsDeep } from 'type-fest'; 30 | 31 | type OO2 = Intersect<{ a: 1, b: 2 }, { b: 4, c: 2 }>; 32 | type OO3 = PickDeep<{ a: 1 } | { a: 2, bb: 2 } | { bb: 11, d: 7 }, 'a'> 33 | 34 | 35 | // type Pet2 = 'dog' | 'cat' | string // LiteralUnion<'dog' | 'cat', string>; 36 | // type Pet2 = 'dog' | 'cat' | string & {} 37 | 38 | 39 | // In covariance (default) 40 | 41 | 42 | 43 | // type O = (a: string, k: number, o: object, ...args: unknown[]) => void; 44 | 45 | // type OO = Parameters 46 | 47 | // type FF = Filter, unknown> 48 | // let rere: FF = ['', 1, {}] 49 | 50 | 51 | type OO = { 52 | name: string, 53 | user: { 54 | lastname?: string, 55 | phone: string, 56 | email?: string 57 | } 58 | } 59 | 60 | type PP = { 61 | str: string, 62 | user: { 63 | phone: number, 64 | address: '' 65 | } 66 | } 67 | 68 | type MM = Replace 69 | 70 | // let m: MM = { 71 | // str: '', 72 | // name: '', 73 | // user: { 74 | // address: '', 75 | // phone: '' 76 | // } 77 | // } 78 | 79 | 80 | // type OO = RequireExactlyOne<{ 81 | // name: string, 82 | // lastname?: string, 83 | // phone: string, 84 | // email?: string 85 | // }> 86 | // let o: OO = {name: ''} 87 | type OO5 = Either<{ a?: 1, b: 1, aa: 1, c: 1 }, 'a' | 'aa' | 'c'> 88 | // type F1l = Compulsory<{ a?: 1, b: 1 | null, '2': 2, '1': 3 }> 89 | // type UserInfo = NonNullable<{ 90 | // name: string, lastname?: string, email?: string, address: { 91 | // street: string, 92 | // number?: number 93 | // } | null 94 | // }> 95 | 96 | type Ar = [1, 2, 3, [4, 5]] 97 | const ar = [1, 2, 3, [4, 5]] as const 98 | 99 | 100 | 101 | // type FF = Filter<[1,2,3,'5'], string> 102 | 103 | 104 | // ts-toolbelt - >200 types // but most of them are very similar to each other - 5.9k => 6.3k 105 | // types-fest - =125 types - 11.k => 12.9k 106 | // utility-types - =57 types - 5.0k => 5.2k 107 | 108 | 109 | 110 | 111 | ///// utility-types vs types-spring: 112 | 113 | // Intersection === Common 114 | // Diff === Diff 115 | // Assign === Merge 116 | // Overwrite == Common . Merge 117 | // UnionToIntersection == IntersectUnion 118 | // $NonMaybeType ~ IsUnion 119 | 120 | // utility-types usefull: 121 | 122 | // DeepReadonly - * 123 | // DeepRequired - * 124 | // $Values - * 125 | // 126 | 127 | 128 | 129 | ///// ts-toolbelt vs types-spring: 130 | 131 | 132 | // Assign === MergeAll // type ExtendedProps = Assign; 133 | // SelectKeys === keyof MapType 134 | // Compulsory === ----- // Make that L's fields cannot be Nullable or Optional (Pointed Required type) 135 | // Extract,Take === ----- // slice(a,b) and slice(0, n) for tuple type (useless) 136 | // Filter === ArrayFilter 137 | // FilterKeys === ArrayFilter[number] 138 | // Flatten === - // type like in js Array.flat 139 | // Group === - // very cool 140 | // Zip === - // very cool 141 | // - === ObjectLength 142 | // - === OptionalExceptOne 143 | // - === ArrayKeys* 144 | // Diff === Diff 145 | 146 | 147 | 148 | 149 | 150 | 151 | // Either === ??? // ? - it is not clear what it does and for what 152 | 153 | /// **Array:** 154 | 155 | // Concat // ! ?useless : - : rare needly 156 | // Drop // ! ?useless : like slice(n) 157 | 158 | /// **Object:** 159 | 160 | // Has == // < ?useless : - : cool, but very useless 161 | // Select == // < ?useless : Extract the fields of O that match M 162 | 163 | 164 | 165 | 166 | 167 | ///// ts-toolbelt vs utility-types: 168 | 169 | // RequiredKeys === RequiredKeys 170 | // SelectKeys === keyof PickByValue 171 | // WritableKeys === MutableKeys 172 | // Writable === Mutable 173 | 174 | 175 | let r: O.Merge<{ a: 1, c: string }, { b: 2, c: 2 }> & {} = { 176 | a: 1, 177 | b: 2, 178 | c: '' 179 | } 180 | //// types-fest vs types-spring vs utility-types: ts-toolbelt 181 | 182 | // MergeDeep == - == - == Merge<'deep'> 183 | // RequiredDeep == - == DeepRequired == Required<'deep'> 184 | // ReadonlyDeep == - == DeepReadonly == Readonly<'deep'> 185 | // OptionalKeysOf ~ ~!NonNullableKey == OptionalKeys == OptionalKeys 186 | // RequiredKeysOf ~NonNullableKey == ~RequiredKeys == ~CompulsoryKeys | RequiredKeys 187 | // Spread == Merge == Assign == Merge 188 | // Merge == Combine == -- == -- 189 | // IsEqual == ?/__use__/? == -- == Equals 190 | // MultidimensionalArray == - == -- == -- 191 | // MultidimensionalReadonlyArray == - == -- == -- 192 | // -- -- == -- == Zip 193 | // FixedLengthArray == ConstrainArray == -- == ? 194 | // KeysMatching == keyof PickByValue == ? 195 | // Exclude> == keyof OmitByValue == ~ExcludeKeys 196 | // Writable == - == == -- // remove all readonly fields 197 | // -- - == Mutable == Writable // makes fields writable 198 | // OverrideProperties == Spread == Overwrite == ~Merge 199 | // RequireAtLeastOne OptionalExceptOne == - == - 200 | // RequireExactlyOne == OneOf == - == - 201 | // ~Common == Intersection // exists in alt branch of types-spring (get dublicate fields) 202 | // Diff == Diff == Diff 203 | // Omit> == Subtract == Extract (the same name as original different type) 204 | // SetFieldType ReplaceType == - == Replace 205 | // - Overlap == - == - 206 | // - ReduceBy == - == - 207 | // == Tail 208 | 209 | 210 | // ... draft... 211 | // Spread Spread == ~Overwrite == ~Merge 212 | 213 | -------------------------------------------------------------------------------- /test-utility-types/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | /* Visit https://aka.ms/tsconfig.json to read more about this file */ 4 | 5 | /* Projects */ 6 | // "incremental": true, /* Enable incremental compilation */ 7 | // "composite": true, /* Enable constraints that allow a TypeScript project to be used with project references. */ 8 | // "tsBuildInfoFile": "./", /* Specify the folder for .tsbuildinfo incremental compilation files. */ 9 | // "disableSourceOfProjectReferenceRedirect": true, /* Disable preferring source files instead of declaration files when referencing composite projects */ 10 | // "disableSolutionSearching": true, /* Opt a project out of multi-project reference checking when editing. */ 11 | // "disableReferencedProjectLoad": true, /* Reduce the number of projects loaded automatically by TypeScript. */ 12 | 13 | /* Language and Environment */ 14 | "target": "es2016", /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */ 15 | // "lib": [], /* Specify a set of bundled library declaration files that describe the target runtime environment. */ 16 | // "jsx": "preserve", /* Specify what JSX code is generated. */ 17 | // "experimentalDecorators": true, /* Enable experimental support for TC39 stage 2 draft decorators. */ 18 | // "emitDecoratorMetadata": true, /* Emit design-type metadata for decorated declarations in source files. */ 19 | // "jsxFactory": "", /* Specify the JSX factory function used when targeting React JSX emit, e.g. 'React.createElement' or 'h' */ 20 | // "jsxFragmentFactory": "", /* Specify the JSX Fragment reference used for fragments when targeting React JSX emit e.g. 'React.Fragment' or 'Fragment'. */ 21 | // "jsxImportSource": "", /* Specify module specifier used to import the JSX factory functions when using `jsx: react-jsx*`.` */ 22 | // "reactNamespace": "", /* Specify the object invoked for `createElement`. This only applies when targeting `react` JSX emit. */ 23 | // "noLib": true, /* Disable including any library files, including the default lib.d.ts. */ 24 | // "useDefineForClassFields": true, /* Emit ECMAScript-standard-compliant class fields. */ 25 | 26 | /* Modules */ 27 | "module": "commonjs", /* Specify what module code is generated. */ 28 | // "rootDir": "./", /* Specify the root folder within your source files. */ 29 | // "moduleResolution": "node", /* Specify how TypeScript looks up a file from a given module specifier. */ 30 | // "baseUrl": "./", /* Specify the base directory to resolve non-relative module names. */ 31 | // "paths": {}, /* Specify a set of entries that re-map imports to additional lookup locations. */ 32 | // "rootDirs": [], /* Allow multiple folders to be treated as one when resolving modules. */ 33 | // "typeRoots": [], /* Specify multiple folders that act like `./node_modules/@types`. */ 34 | // "types": [], /* Specify type package names to be included without being referenced in a source file. */ 35 | // "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */ 36 | // "resolveJsonModule": true, /* Enable importing .json files */ 37 | // "noResolve": true, /* Disallow `import`s, `require`s or ``s from expanding the number of files TypeScript should add to a project. */ 38 | 39 | /* JavaScript Support */ 40 | // "allowJs": true, /* Allow JavaScript files to be a part of your program. Use the `checkJS` option to get errors from these files. */ 41 | // "checkJs": true, /* Enable error reporting in type-checked JavaScript files. */ 42 | // "maxNodeModuleJsDepth": 1, /* Specify the maximum folder depth used for checking JavaScript files from `node_modules`. Only applicable with `allowJs`. */ 43 | 44 | /* Emit */ 45 | // "declaration": true, /* Generate .d.ts files from TypeScript and JavaScript files in your project. */ 46 | // "declarationMap": true, /* Create sourcemaps for d.ts files. */ 47 | // "emitDeclarationOnly": true, /* Only output d.ts files and not JavaScript files. */ 48 | // "sourceMap": true, /* Create source map files for emitted JavaScript files. */ 49 | // "outFile": "./", /* Specify a file that bundles all outputs into one JavaScript file. If `declaration` is true, also designates a file that bundles all .d.ts output. */ 50 | // "outDir": "./", /* Specify an output folder for all emitted files. */ 51 | // "removeComments": true, /* Disable emitting comments. */ 52 | // "noEmit": true, /* Disable emitting files from a compilation. */ 53 | // "importHelpers": true, /* Allow importing helper functions from tslib once per project, instead of including them per-file. */ 54 | // "importsNotUsedAsValues": "remove", /* Specify emit/checking behavior for imports that are only used for types */ 55 | // "downlevelIteration": true, /* Emit more compliant, but verbose and less performant JavaScript for iteration. */ 56 | // "sourceRoot": "", /* Specify the root path for debuggers to find the reference source code. */ 57 | // "mapRoot": "", /* Specify the location where debugger should locate map files instead of generated locations. */ 58 | // "inlineSourceMap": true, /* Include sourcemap files inside the emitted JavaScript. */ 59 | // "inlineSources": true, /* Include source code in the sourcemaps inside the emitted JavaScript. */ 60 | // "emitBOM": true, /* Emit a UTF-8 Byte Order Mark (BOM) in the beginning of output files. */ 61 | // "newLine": "crlf", /* Set the newline character for emitting files. */ 62 | // "stripInternal": true, /* Disable emitting declarations that have `@internal` in their JSDoc comments. */ 63 | // "noEmitHelpers": true, /* Disable generating custom helper functions like `__extends` in compiled output. */ 64 | // "noEmitOnError": true, /* Disable emitting files if any type checking errors are reported. */ 65 | // "preserveConstEnums": true, /* Disable erasing `const enum` declarations in generated code. */ 66 | // "declarationDir": "./", /* Specify the output directory for generated declaration files. */ 67 | // "preserveValueImports": true, /* Preserve unused imported values in the JavaScript output that would otherwise be removed. */ 68 | 69 | /* Interop Constraints */ 70 | // "isolatedModules": true, /* Ensure that each file can be safely transpiled without relying on other imports. */ 71 | // "allowSyntheticDefaultImports": true, /* Allow 'import x from y' when a module doesn't have a default export. */ 72 | "esModuleInterop": true, /* Emit additional JavaScript to ease support for importing CommonJS modules. This enables `allowSyntheticDefaultImports` for type compatibility. */ 73 | // "preserveSymlinks": true, /* Disable resolving symlinks to their realpath. This correlates to the same flag in node. */ 74 | "forceConsistentCasingInFileNames": true, /* Ensure that casing is correct in imports. */ 75 | 76 | /* Type Checking */ 77 | "strict": true, /* Enable all strict type-checking options. */ 78 | // "noImplicitAny": true, /* Enable error reporting for expressions and declarations with an implied `any` type.. */ 79 | // "strictNullChecks": true, /* When type checking, take into account `null` and `undefined`. */ 80 | // "strictFunctionTypes": true, /* When assigning functions, check to ensure parameters and the return values are subtype-compatible. */ 81 | // "strictBindCallApply": true, /* Check that the arguments for `bind`, `call`, and `apply` methods match the original function. */ 82 | // "strictPropertyInitialization": true, /* Check for class properties that are declared but not set in the constructor. */ 83 | // "noImplicitThis": true, /* Enable error reporting when `this` is given the type `any`. */ 84 | // "useUnknownInCatchVariables": true, /* Type catch clause variables as 'unknown' instead of 'any'. */ 85 | // "alwaysStrict": true, /* Ensure 'use strict' is always emitted. */ 86 | // "noUnusedLocals": true, /* Enable error reporting when a local variables aren't read. */ 87 | // "noUnusedParameters": true, /* Raise an error when a function parameter isn't read */ 88 | // "exactOptionalPropertyTypes": true, /* Interpret optional property types as written, rather than adding 'undefined'. */ 89 | // "noImplicitReturns": true, /* Enable error reporting for codepaths that do not explicitly return in a function. */ 90 | // "noFallthroughCasesInSwitch": true, /* Enable error reporting for fallthrough cases in switch statements. */ 91 | // "noUncheckedIndexedAccess": true, /* Include 'undefined' in index signature results */ 92 | // "noImplicitOverride": true, /* Ensure overriding members in derived classes are marked with an override modifier. */ 93 | // "noPropertyAccessFromIndexSignature": true, /* Enforces using indexed accessors for keys declared using an indexed type */ 94 | // "allowUnusedLabels": true, /* Disable error reporting for unused labels. */ 95 | // "allowUnreachableCode": true, /* Disable error reporting for unreachable code. */ 96 | 97 | /* Completeness */ 98 | // "skipDefaultLibCheck": true, /* Skip type checking .d.ts files that are included with TypeScript. */ 99 | "skipLibCheck": true /* Skip type checking all .d.ts files. */ 100 | }, 101 | "include": [ 102 | // "./node_modules/utility-types", 103 | "./node_modules/type-fest", 104 | // "./node_modules/ts-toolbelt", 105 | "./node_modules/types-spring", 106 | "./sources" 107 | ] 108 | } 109 | -------------------------------------------------------------------------------- /tests/dom.ts: -------------------------------------------------------------------------------- 1 | //@ts-check 2 | 3 | 4 | /// Node.querySelector: 5 | 6 | const elem = document.querySelector('.cls'); if (elem) elem.innerHTML = '' // is Element 7 | const tag = document.querySelector('input'); if (tag) tag.value = ''; // is HTMLInputElement 8 | 9 | 10 | const force = document.querySelector('#id'); if (force) force.innerText = '' // is HTMLElement 11 | const forceType = document.querySelector('a a input'); if (forceType) forceType.value = '' // is HTMLInputElement 12 | 13 | 14 | const cls = document.querySelector('input.cls'); if (cls) cls.value = '' // is HTMLInputElement 15 | const id = document.querySelector('input#id'); if (id) id.value = '' // is HTMLInputElement 16 | const child = document.querySelector('.cls input') // is HTMLInputElement 17 | && document.querySelector('.cls input#cls') 18 | && document.querySelector('.cls input.cls'); if (child) child.value = '' 19 | const nextchild = document.querySelector('.cls>input') // is HTMLInputElement 20 | && document.querySelector('.cls>input#cls') 21 | && document.querySelector('.cls>input.cls'); if (nextchild) nextchild.value = '' 22 | const neighbor = document.querySelector('.cls+input') // is HTMLInputElement 23 | && document.querySelector('.cls+input#cls') 24 | && document.querySelector('.cls+input.cls'); if (neighbor) neighbor.value = '' 25 | const kindred = document.querySelector('.cls+input') // is HTMLInputElement 26 | && document.querySelector('.cls~input#cls') 27 | && document.querySelector('.cls~input.cls'); if (kindred) kindred.value = '' 28 | 29 | const tilda3 = document.querySelector('a~a~input'); if (tilda3) tilda3.innerText = '' // is HTMLElement 30 | const _wsps1 = document.querySelector('a a input'); if (_wsps1) _wsps1.innerText = '' // is HTMLElement 31 | 32 | const misspell = document.querySelector('a.cls'); // is HTMLAnchorElement | null 33 | misspell?.value.replace('', '') 34 | 35 | 36 | 37 | 38 | 39 | //@ts-expect-error 40 | const _id = document.querySelector('#id'); if (_id) _id.innerText = '' // is Element 41 | //@ts-expect-error 42 | const _cls = document.querySelector('.cls'); if (_cls) _cls.innerText = '' // is Element 43 | //@ts-expect-error 44 | const _attr = document.querySelector('div.cls[attr~=value]'); if (_attr) _attr.innerText = '' // is Element 45 | //@ts-expect-error 46 | const _wsp = document.querySelector('div.cls[attr="a b"]'); if (_wsp) _wsp.innerText = '' // is Element 47 | //@ts-expect-error 48 | const _attr_value = document.querySelector('div.cls[attr="a a.div"]'); if (_attr_value) _attr_value.innerText = '' // is Element 49 | 50 | //@ts-expect-error 51 | const _wsps2 = document.querySelector('a a input'); if (_wsps2) _wsps2.value = '' // is HTMLElement 52 | //@ts-expect-error 53 | const _tilda3 = document.querySelector('a~a~input'); if (_tilda3) _tilda3.value = '' // is HTMLElement 54 | 55 | 56 | 57 | 58 | /// HTMLElement.cloneNode: 59 | 60 | const element = document.getElementById('id')?.cloneNode(); 61 | if (element) element.innerText = '' 62 | 63 | 64 | 65 | /// MouseEvent: 66 | 67 | function uiEvent(event: UIEvent) { 68 | if (event.target) var s: string | null = event.target.textContent 69 | } 70 | 71 | function mouseEvent(event: MouseEvent & UIEvent) { 72 | if (event.target) var s: string | null = event.target.textContent 73 | if (event.currentTarget) var s: string | null = event.currentTarget.textContent 74 | } 75 | 76 | function keyEvent(event: KeyboardEvent) { 77 | //@ts-expect-error 78 | if (event.target) var s: string | null = event.target.value 79 | if (event.currentTarget) var s: string | null = event.currentTarget.value 80 | } 81 | 82 | function event__window(event: MouseEvent) { 83 | event.pageX 84 | if (event.target) var s: string | null = 'self' in event.target ? '' : event.target.textContent 85 | if (event.currentTarget) var s: string | null = event.currentTarget.origin 86 | } 87 | 88 | function strictWindowEvent(event: MouseEvent) { 89 | event.pageX 90 | event.target?.innerHTML 91 | } 92 | 93 | window.addEventListener('click', event__window) 94 | window.addEventListener('click', e => { 95 | if (e.target) { 96 | if (e.isTrusted === true) { e.target.innerHTML } 97 | if ('atob' in e.target) { 98 | e.target.alert(9) 99 | } 100 | else { // 'nodeName' in 101 | e.target.textContent = e.currentTarget?.origin || ''; 102 | } 103 | } 104 | }) 105 | 106 | 107 | 108 | /// addEventListener: 109 | 110 | 111 | 112 | { 113 | /// generic: 114 | window.addEventListener<'click', Element>('click', e => { 115 | e.target?.innerHTML 116 | }) 117 | const elem = document.querySelector('div') 118 | if (elem) elem.addEventListener('click', e => { 119 | e.target 120 | e.currentTarget 121 | }) 122 | 123 | let tt: EventTarget & {a?: 1} = new EventTarget(); 124 | tt.addEventListener('click', e => e.currentTarget == e.target) 125 | 126 | document.querySelector('div.a')?.addEventListener('click', (e: MouseEvent) => { 127 | let tc = e.target?.textContent 128 | //@ts-expect-error 129 | let tv = e.target?.innerText 130 | let v = e.currentTarget?.innerText 131 | }) 132 | document.addEventListener('click', function (event) { 133 | //@ts-expect-error 134 | let r = event.target?.body // is Node 135 | let b = event.currentTarget?.body 136 | }) 137 | document.querySelector('input.a')?.addEventListener('focus', e => { 138 | let v = e.currentTarget?.value 139 | let tv = e.target.value 140 | let tc = e.target.textContent 141 | }) 142 | document.querySelector('input.a')?.addEventListener('input', e => { 143 | let v = e.currentTarget?.value 144 | let tv = e.target.value 145 | let tc = e.target.textContent 146 | e.inputType?.indexOf('a') 147 | //@ts-expect-error 148 | e.inputType.indexOf('a') 149 | }) 150 | document.querySelector('textarea.a')?.addEventListener('input', e => { 151 | let v = e.currentTarget?.value 152 | let tv = e.target.value 153 | let tc = e.target.textContent 154 | e.inputType.indexOf('a') 155 | }) 156 | 157 | document.addEventListener('click', e => { 158 | let v = e.currentTarget?.body 159 | let tc = e.target?.textContent 160 | }) 161 | } 162 | 163 | -------------------------------------------------------------------------------- /tests/ecma.ts: -------------------------------------------------------------------------------- 1 | //@ts-check 2 | 3 | 4 | /// Array.map 5 | 6 | 7 | const a = [1, 2, 3] as const; 8 | let arr = a.map(r => r + '') 9 | //@ts-expect-error 10 | let item = arr[3] 11 | 12 | 13 | /// Array.isArray 14 | 15 | 16 | function checkIsReadonlyArray(a: { a: 1 } | ReadonlyArray) { 17 | if (Array.isArray(a)) { 18 | //@ts-expect-error 19 | a[0] = 1 20 | //@ts-expect-error 21 | a.forEach(item => item.f()) 22 | } 23 | else { 24 | a.a 25 | } 26 | } 27 | 28 | function checkIsArray(a: { a: 1 } | Array) { 29 | if (Array.isArray(a)) { 30 | a[0] = 1 31 | //@ts-expect-error 32 | a.forEach(item => item.f()) 33 | } 34 | else a.a 35 | } 36 | 37 | 38 | /// Array.indexOf 39 | 40 | 41 | function getIndex(arg: number) { 42 | //@ts-expect-error 43 | var index = a.indexOf(arg) 44 | var index = a.indexOf(arg) 45 | //@ts-expect-error 46 | var index = a.indexOf(arg) 47 | return index 48 | } 49 | 50 | 51 | 52 | /// Object.assign 53 | 54 | const o1 = { a: 1, b: 1 }; 55 | const o2 = { b: '', c: 1 } 56 | 57 | const o = Object.assign(o1, o2) 58 | o.b = 'ok' 59 | 60 | 61 | /// Object.defineProperty 62 | 63 | 64 | const r = Object.defineProperty({ a: 1 }, "name", { 65 | value: 1, 66 | }); 67 | 68 | 69 | let n: number = r.a 70 | let v: number = r.name; 71 | //@ts-expect-error 72 | r.name = v 73 | 74 | 75 | 76 | /// Object.defineProperties 77 | 78 | 79 | { 80 | { 81 | /// custom (origin): 82 | 83 | const rs = Object.defineProperties<{ a: 1, d?: number | string }>({ a: 1 }, { 84 | d: { 85 | // value: 1, 86 | // writable: true 87 | set(a) { }, 88 | get() { 89 | return 1 90 | } 91 | } 92 | }); 93 | rs.a = 1 94 | rs.d = '' 95 | } 96 | { 97 | /// get set: 98 | 99 | const rs = Object.defineProperties({ a: 1 }, { 100 | d: { 101 | // value: 1, 102 | // writable: true 103 | set(a) {}, 104 | get() { 105 | return 1 106 | } 107 | } 108 | }); 109 | 110 | let na: number = rs.a 111 | let nd: number = rs.d 112 | //@ts-expect-error: does not exists 113 | let nn = rs.name; 114 | //@ts-expect-error: legacy field => string != number 115 | let nsa: string = rs.a 116 | //@ts-expect-error: new field => string != number 117 | let nsd: string = rs.d 118 | rs.a = na; 119 | rs.d = nd; 120 | } 121 | { 122 | /// get 123 | 124 | const rs = Object.defineProperties({ a: 1 }, { 125 | d: { 126 | get() { 127 | return 1 128 | } 129 | } 130 | }); 131 | 132 | let na: number = rs.a 133 | let nd: number = rs.d 134 | //@ts-expect-error: does not exists 135 | let nn = rs.name; 136 | //@ts-expect-error: legacy field => string != number 137 | let nsa: string = rs.a 138 | //@ts-expect-error: new field => string != number 139 | let nsd: string = rs.d 140 | rs.a = na; 141 | //@ts-expect-error 142 | rs.d = nd; 143 | } 144 | 145 | { 146 | /// writable: true 147 | 148 | const rs = Object.defineProperties({ a: 1 }, { 149 | d: { 150 | value: 1, 151 | writable: true 152 | } 153 | }); 154 | 155 | let na: number = rs.a 156 | let nd: number = rs.d 157 | //@ts-expect-error: does not exists 158 | let nn = rs.name; 159 | //@ts-expect-error: legacy field => string != number 160 | let nsa: string = rs.a 161 | //@ts-expect-error: new field => string != number 162 | let nsd: string = rs.d 163 | rs.a = na; 164 | rs.d = nd; 165 | } 166 | 167 | { 168 | /// writable: false 169 | 170 | const rs = Object.defineProperties({ a: 1 }, { 171 | d: { 172 | value: 1, 173 | writable: false 174 | } 175 | }); 176 | 177 | let na: number = rs.a 178 | let nd: number = rs.d 179 | //@ts-expect-error: does not exists 180 | let nn = rs.name; 181 | //@ts-expect-error: legacy field => string != number 182 | let nsa: string = rs.a 183 | //@ts-expect-error: new field => string != number 184 | let nsd: string = rs.d 185 | rs.a = na; 186 | 187 | //@ts-expect-error ! 188 | rs.d = nd; 189 | } 190 | 191 | { 192 | /// writable: undefined 193 | 194 | const rs = Object.defineProperties({ a: 1 }, { 195 | d: { 196 | value: 1, 197 | } 198 | }); 199 | 200 | let na: number = rs.a 201 | let nd: number = rs.d 202 | //@ts-expect-error: does not exists 203 | let nn = rs.name; 204 | //@ts-expect-error: legacy field => string != number 205 | let nsa: string = rs.a 206 | //@ts-expect-error: new field => string != number 207 | let nsd: string = rs.d 208 | rs.a = na; 209 | 210 | //@ts-expect-error ! 211 | rs.d = nd; 212 | } 213 | 214 | } 215 | 216 | 217 | 218 | /// Object.create: 219 | 220 | { 221 | let o = Object.create(null) 222 | //@ts-expect-error 223 | if (o === 1){} 224 | } 225 | 226 | 227 | /// Object.keys: 228 | 229 | 230 | // let k = Object.keys({ a: 1 }) 231 | // function succesFunc(arg: string) { 232 | // //@ts-expect-error 233 | // k[0] = arg; 234 | // } 235 | 236 | // let ku = Object.keys({ a: 1 }) 237 | // function func(arg: string) { 238 | // ku[0] = arg; 239 | // } 240 | 241 | 242 | /// setPrototypeOf: 243 | 244 | { 245 | let o = Object.setPrototypeOf({ a: 1 }, { b: 1 }) 246 | //@ts-expect-error 247 | o.a = '' 248 | //@ts-expect-error 249 | o.b = '' 250 | } -------------------------------------------------------------------------------- /tests/utility.ts: -------------------------------------------------------------------------------- 1 | //@ts-check 2 | 3 | import type { 4 | OmitNullable, 5 | _ParseInt, 6 | NonNullableKey, 7 | ConstrainedArray, 8 | WideArray, 9 | ConvertTupleType, 10 | Enumerate, 11 | Ranged, Sequence, 12 | ArrayFilter, 13 | MapArray, 14 | MapType as MapTypeValue, 15 | KeysMatching, 16 | IntersectUnion, 17 | IsUnion, 18 | Common, 19 | Diff, 20 | Merge, Spread, 21 | OptionalExceptOne, 22 | ScreenType, 23 | ObjectLength, 24 | KeysArray, 25 | ReplaceTypes, 26 | Join, 27 | OneOf, 28 | // Combine_, 29 | Overlap as Overlap, 30 | ReduceBy, 31 | // PickByKey 32 | } from "../sources/utils"; 33 | 34 | 35 | /// KeysArray: 36 | 37 | 38 | type ObjType = { 39 | a: string; 40 | b: string; 41 | c: string; 42 | }; 43 | 44 | { 45 | //@ts-expect-error => type "d" is not assignable to type "a" | "b" | "c". 46 | const bar: KeysArray = ["d"]; 47 | //@ts-expect-error => type '["a", "b", "c", "d"]' is not assignable to type ["a", "b", "c"] 48 | const foo: KeysArray = ["a", "b", "c", "d"]; 49 | 50 | const objKeys: KeysArray & {} = ["a", "b", "c"]; 51 | 52 | const objKeys$: KeysArray = ["a", "c", "b"]; 53 | 54 | //@ts-expect-error => string[] is not ussignible to `Object with too much (6) fields amount (expected less than 6) passed to KeysArray type` 55 | let objKeys8: KeysArray, 6> = ["a", "b", "c", 'lastname', 'email', 'phonenumber'] 56 | } 57 | 58 | 59 | 60 | /// NonNullableKeys 61 | 62 | 63 | type User = { 64 | name: string; 65 | lastname: string; 66 | email?: string; 67 | phonenumber: string | null; 68 | }; 69 | 70 | { 71 | 72 | let a: NonNullableKey & {} = 'name' 73 | //@ts-expect-error 74 | let b: NonNullableKey = 'email' 75 | //@ts-expect-error 76 | let c: NonNullableKey = 'phonenumber' 77 | } 78 | 79 | 80 | 81 | 82 | /// OmitNullable 83 | 84 | type UserType = { 85 | name: string; 86 | email: string | null; 87 | }; 88 | 89 | //@ts-expect-error 90 | let u: OmitNullable = { name: '', email: '' } 91 | 92 | 93 | 94 | /// ParseInt 95 | 96 | const num: _ParseInt<'7'> = 7 97 | 98 | 99 | 100 | /// ConstraitArray 101 | 102 | let names: ConstrainedArray<2, boolean> = [false, true] 103 | //@ts-expect-error 104 | let names_3: ConstrainedArray<2, boolean> = [false, true, false] 105 | //@ts-expect-error 106 | let strings: ConstrainedArray<2, boolean> = ['', ''] 107 | 108 | 109 | 110 | /// Indexes 111 | 112 | export const testArray = [ 113 | "test1", 114 | "test2", 115 | "test3", 116 | "test4" 117 | ] as const; 118 | 119 | let indexes: Indexes = 3 120 | //@ts-expect-error 121 | let overloaded: Indexes = 4 122 | 123 | 124 | 125 | /// Sequence 126 | 127 | let seq: Sequence<3> = [0, 1, 2] 128 | //@ts-expect-error 129 | let faseq: Sequence<3> = [0, 1, 3] 130 | //@ts-expect-error 131 | let leseq: Sequence<3> = [0, 1] 132 | //@ts-expect-error 133 | let moseq: Sequence<3> = [0, 1, 2, 3] 134 | 135 | 136 | 137 | /// Merge 138 | 139 | type A = { 140 | a: number, 141 | b: string 142 | } 143 | type B = { 144 | b: boolean, 145 | c: number 146 | } 147 | 148 | let m: Merge = { a: 1, b: true, c: 1 } 149 | //@ts-expect-error 150 | let ms: Merge = { a: 1, b: '', c: 1 } 151 | 152 | 153 | /// MergeAll 154 | 155 | 156 | { 157 | let c: MergeAll<[A, B, { d: 7 }]> = { a: 1, b: true, c: 1, d: 7 } 158 | //@ts-expect-error 159 | let cs: MergeAll<[A, B, { d: 7 }]> = { a: 1, b: '', c: 1, d: 7 } 160 | } 161 | 162 | 163 | 164 | /// WideArray 165 | 166 | 167 | const arr = [1, 2, 3] as const 168 | let ar: WideArray = [0, 0, 0,] 169 | //@ts-expect-error 170 | let ar2: WideArray = [0, 0] 171 | //@ts-expect-error 172 | let ar4: WideArray = [0, 0, 0, 0] 173 | //@ts-expect-error 174 | let ars: WideArray = ['', '', ''] 175 | 176 | 177 | /// ConvertTupleType 178 | 179 | let r: ConvertTupleType = ['', '', ''] 180 | //@ts-expect-error 181 | let nr: ConvertTupleType = [1, 2, 3] 182 | 183 | 184 | 185 | /// Enumerate 186 | 187 | 188 | const en: Enumerate<5> = 0 189 | //@ts-expect-error 190 | const en5: Enumerate<5> = 5 191 | 192 | 193 | 194 | /// Range 195 | 196 | const n: Ranged<5, 10> & {} = 5; 197 | //@ts-expect-error 198 | const n0: Ranged<5, 10> = 0; 199 | //@ts-expect-error 200 | const n10: Ranged<5, 10> = 10; 201 | 202 | 203 | 204 | 205 | /// KeysMatching 206 | 207 | { 208 | let a = { a: 1, b: '', c: '' }; 209 | //@ts-expect-error 210 | let keysa: KeysMatching = 'a' 211 | let keys: KeysMatching & {} = 'b' 212 | } 213 | 214 | 215 | /// ArrayFilter 216 | 217 | const _a = [1, 2, '']; 218 | let rt: ArrayFilter = [1, 2, 3] 219 | //@ts-expect-error 220 | let rr: ArrayFilter = [1, 2, 3, ''] 221 | 222 | 223 | 224 | 225 | /// MapType 226 | { 227 | type O = { 228 | a: { 229 | value: number, 230 | }, 231 | b: { 232 | value: string, 233 | } 234 | } 235 | 236 | function func1(yyy: MapTypeValue) { 237 | yyy.b = '' 238 | //@ts-expect-error 239 | yyy.b = 1 240 | yyy.a = 1 241 | //@ts-expect-error 242 | yyy.a = '' 243 | } 244 | } 245 | 246 | 247 | 248 | 249 | /// MapArray 250 | 251 | { 252 | type A = [ 253 | { 254 | a: number, b: string 255 | }, 256 | { 257 | a: string 258 | } 259 | ] 260 | type R = MapArray 261 | let r: R = [1, '2']; 262 | //@ts-expect-error 263 | let r1: R = [1, 2, 3]; 264 | //@ts-expect-error 265 | let r2: R = [1]; 266 | //@ts-expect-error 267 | let r3: R = ['', '']; 268 | //@ts-expect-error 269 | let r4: R = [{ a: number }, { a: number }]; 270 | 271 | { 272 | type R = MapArray, 'a'> 273 | let r: R = [1, 2]; 274 | let r1: R = [1, 2, 3]; 275 | let r2: R = [1]; 276 | //@ts-expect-error 277 | let r3: R = ['', '']; 278 | //@ts-expect-error 279 | let r4: R = [{ a: number }, { a: number }]; 280 | } 281 | 282 | } 283 | 284 | 285 | 286 | /// IntersectUnion: 287 | 288 | { 289 | type A = { a: 1 } 290 | type B = { b: 1 } 291 | type AB = A | B 292 | let a: IntersectUnion = { a: 1, b: 1 } 293 | // let a: IntersectUnion<{ a: 1 } | { b: 1 }> = { a: 1, b: 1 } 294 | let b: { a: 1 } & { b: 1 } = a 295 | } 296 | 297 | 298 | /// IsUnion 299 | { 300 | let a: IsUnion = true 301 | let b: IsUnion = false 302 | } 303 | 304 | 305 | /// Common: 306 | { 307 | type A = { a: number, b: number, c: number } 308 | type B = { aa: number, b: number, c: string } 309 | let c: Common = { 310 | b: 1, 311 | c: '' 312 | } 313 | //@ts-expect-error 314 | c.a 315 | //@ts-expect-error 316 | c.aa 317 | } 318 | 319 | /// Diff: 320 | { 321 | type A = { a: number, b: number, c: number } 322 | type B = { aa: number, b: number, c: string } 323 | let c: Diff = { a: 1 } 324 | } 325 | 326 | 327 | /// OptionalExceptOne 328 | { 329 | type O = OptionalExceptOne<{ a: 1, b: 1, c: 1 }> 330 | //@ts-expect-error 331 | let o: O = {} 332 | let oa: O = { a: 1 } 333 | let ob: O = { b: 1 } 334 | let oc: O = { c: 1 } 335 | let ooo: O = { a: 1, b: 1, c: 1 } 336 | //@ts-expect-error 337 | let od: O = { d: 1 } 338 | } 339 | 340 | 341 | /// ScreenType 342 | // { 343 | // type MyLikeName = ScreenType 344 | // const s: MyLikeName = '1' 345 | // const arf = ['1'] 346 | // arf.indexOf(s) 347 | // } 348 | 349 | 350 | 351 | /// ObjectLength 352 | { 353 | type Table = { 354 | id: number; 355 | id_user: string; 356 | is_active: boolean; 357 | 1: ''; 358 | }; 359 | let r4: ObjectLength = 4; 360 | //@ts-expect-error 361 | let r1: ObjectLength
= 1; 362 | //@ts-expect-error 363 | let r5: ObjectLength
= 5; 364 | } 365 | 366 | 367 | /// Join 368 | { 369 | type A = [{ a: number }, { c: number }, { d: string }] 370 | type O = Join 371 | let o: O = { 372 | a: 1, 373 | c: 3, 374 | d: '' 375 | } 376 | } 377 | 378 | 379 | /// OneOf 380 | { 381 | type Params = { 382 | a: 1, 383 | b: 1, 384 | c: 1 385 | } 386 | 387 | let a: OneOf = {a: 1} 388 | let b: OneOf = {b: 1} 389 | //@ts-expect-error 390 | let ab: OneOf = {a: 1, b: 1} 391 | //@ts-expect-error 392 | let abc: OneOf = {a: 1, b: 1, c: 1} 393 | } 394 | 395 | 396 | 397 | /// ReplaceTypes 398 | { 399 | type Profile = { 400 | s: string, b: number, 401 | c: { f: string } 402 | } 403 | 404 | let rrr: ReplaceTypes = { 405 | s: 1, 406 | b: 1, 407 | c: {f: 1} 408 | } 409 | 410 | let tt: ReplaceTypes<['', '', 5], string, 0> = [0, 0, 5]; 411 | //@ts-expect-error 412 | let t1: ReplaceTypes<['', '', 5], string, 0> = [0, 1, 5]; 413 | } 414 | 415 | 416 | /// Combine 417 | { 418 | // type C = Combine_<{ a: number, b: number }, { b: string, c: string }>; 419 | // let c: C = { a: 1, b: 1, c: 'string' } 420 | // let cs: C = { a: 1, b: '', c: 'string' } 421 | // //@ts-expect-error 422 | // let cb: C = { a: 1, b: false, c: 'string' } 423 | // //@ts-expect-error 424 | // let cn: C = { a: 1, b: '', c: 1} 425 | } 426 | 427 | 428 | 429 | /// Overlay 430 | 431 | { 432 | type AA = { a: number, b: number } | { b: string, c: string } 433 | type O = Overlap // => { a: number, b: number | string, c: string } 434 | let o: O = { a: 1, b: 1, c: '' } 435 | let os: O = { a: 1, b: '', c: '' } 436 | //@ts-expect-error 437 | let osn: O = { a: 1, b: '', c: 0 } 438 | } 439 | 440 | 441 | /// ReduceBy 442 | 443 | { 444 | type R = ReduceBy<[{ a: 'a1', b: '1' }, { a: 'a2', b: '2' }], 'a'> 445 | let r: R = { a1: { b: '1', a: 'a1' }, a2: { b: '2', a: 'a2' } }; 446 | 447 | const ar = [{ a: 'a1', b: '1' }, { a: 'a2', b: '2' }] as const 448 | const o = ar.reduce((acc, a) => ({ [a.a]: a, ...acc }), {}) as ReduceBy 449 | } 450 | 451 | 452 | 453 | //@ Another capabilites: 454 | 455 | 456 | type L = ObjectLength; // 3 457 | var ks: Sequence[number] = 2 // 0 | 1 | 2 458 | var ks: Enumerate = 2 // 0 | 1 | 2 459 | 460 | 461 | 462 | 463 | -------------------------------------------------------------------------------- /tests_origin/$__problems__research.ts: -------------------------------------------------------------------------------- 1 | /** known unresolved TS bugs */ 2 | // (unresolved by me too) 3 | 4 | 5 | // #1 `leaky type guarding on objects union` 6 | 7 | { 8 | interface A { a(): string }; 9 | interface B { b(): string }; 10 | 11 | function f(x: A | B): string { 12 | if ("a" in x) { 13 | return x.a(); // runtime error! 14 | } else { 15 | return x.b(); 16 | } 17 | } 18 | 19 | const x = { a: 10, b() { return "hello"; } }; 20 | const y: B = x; 21 | f(y); 22 | } 23 | 24 | // or: 25 | 26 | function func(arg: {a: string, b?: string} | {a: string, b: string, c?: string}){ 27 | 28 | if ('c' in arg){ 29 | arg.b.toString() // runtime error! 30 | } 31 | } 32 | 33 | let a = {a: '', c: ''} 34 | 35 | func(a) 36 | 37 | 38 | 39 | 40 | // #2 `bad signature` 41 | 42 | Object.defineProperty(1, '', {}) // runtime error! 43 | Object.defineProperties(100, {}) // runtime error! 44 | 45 | 46 | 47 | 48 | // # 3 `covariance` 49 | 50 | interface IBar { 51 | [key: string]: IBar[keyof IBar], 52 | a: number 53 | } 54 | 55 | type Bar = { a: number; } 56 | 57 | const bar2 = { a: 10, b: '30' } 58 | const bar: Bar = bar2 59 | 60 | 61 | const foo = (a: IBar) => { 62 | let y = Object.entries(a) 63 | y.map(u => u[1].toFixed()) // runtime error! 64 | } 65 | 66 | foo(bar) 67 | 68 | 69 | 70 | -------------------------------------------------------------------------------- /tests_origin/$__proposals.ts: -------------------------------------------------------------------------------- 1 | /// types-spring 2 | 3 | const ar = new Array(2) // number[] => [number, number] - set fix length array 4 | 5 | // too narrow type 6 | 7 | 8 | /// 2 9 | 10 | { 11 | let rr = Object.defineProperty({ d: 4 }, '1', { // defined prop name should be optional field inside origin object type. else - error? real? 12 | value: true 13 | }) 14 | 15 | /** 16 | * @declined declined because of unpossinility to redefine default beh. 17 | * */ 18 | } 19 | 20 | 21 | 22 | /// 3 23 | { 24 | /** 25 | * @declined stiil because of the type is exists inside another package (toolbelt). But take to note(!) 26 | */ 27 | // slice() => tuple 28 | } -------------------------------------------------------------------------------- /tests_origin/dom.ts: -------------------------------------------------------------------------------- 1 | //@ts-check 2 | 3 | /** 4 | * The purpose of this test is to check whether the flaws in the original package have been eliminated 5 | */ 6 | 7 | /// querySelector: 8 | 9 | const tag = document.querySelector('div'); if (tag) tag.innerText = ''; // success 10 | //@ts-expect-error 11 | const cls = document.querySelector('div.cls'); if (cls) cls.innerText = '' // is error 12 | //@ts-expect-error 13 | const id = document.querySelector('div#id'); if (id) id.innerText = '' // is error 14 | //@ts-expect-error 15 | const child = document.querySelector('.cls div'); if(child) child.innerText = '' // is error 16 | //@ts-expect-error 17 | const childCls = document.querySelector('.cls div.cls'); if (childCls) childCls.innerText = '' // is error 18 | //@ts-expect-error 19 | const childId = document.querySelector('.cls div#id'); if (childId) childId.innerText = '' // is error 20 | //@ts-expect-error 21 | const nextchild = document.querySelector('.cls>div'); if (nextchild) nextchild.innerText = '' // is error 22 | //@ts-expect-error 23 | const nextchildId = document.querySelector('.cls>div#id'); if (nextchildId) nextchildId.innerText = '' // is error 24 | //@ts-expect-error 25 | const nextchildCls = document.querySelector('.cls>div.cls'); if (nextchildCls) nextchildCls.innerText = '' // is error 26 | //@ts-expect-error 27 | const neighbor = document.querySelector('.cls+div'); if (neighbor) neighbor.innerText = '' // is error 28 | //@ts-expect-error 29 | const neighborID = document.querySelector('.cls+div#id'); if (neighborID) neighborID.innerText = '' // is error 30 | //@ts-expect-error 31 | const neighborCls = document.querySelector('.cls+div.cls'); if (neighborID) neighborID.innerText = '' // is error 32 | //@ts-expect-error 33 | const kindred = document.querySelector('.cls~div'); if (kindred) kindred.innerText = '' // is error 34 | //@ts-expect-error 35 | const kindredID = document.querySelector('.cls~div#id'); if (kindredID) kindredID.innerText = '' // is error 36 | //@ts-expect-error 37 | const kindredCls = document.querySelector('.cls~div.cls'); if (kindredID) kindredID.innerText = '' // is error 38 | 39 | 40 | 41 | 42 | /// cloneNode: 43 | 44 | const element = document.getElementById('id')?.cloneNode(); 45 | //@ts-expect-error 46 | if (element) element.innerText = '' 47 | 48 | 49 | 50 | 51 | /// MouseEvent: 52 | 53 | function uiEvent(event: UIEvent) { 54 | //@ts-expect-error 55 | if (event.target) var s: string | null = event.target.textContent 56 | } 57 | window.addEventListener('click', e => { 58 | if (e.target) { 59 | //@ts-expect-error 60 | let v = e.currentTarget?.origin || ''; 61 | //@ts-expect-error 62 | e.target.textContent = v; 63 | } 64 | }) 65 | 66 | /// addEventListener: 67 | 68 | 69 | 70 | { 71 | let tt = new EventTarget(); 72 | tt.addEventListener('click', e => e.currentTarget == e.target) 73 | 74 | let div_a = document.querySelector('div.a'); 75 | let input = document.querySelector('div.a'); 76 | let txtar = document.querySelector('div.a'); 77 | 78 | div_a?.addEventListener('click', e => { 79 | //@ts-expect-error 80 | let tv = e.target?.innerText 81 | //@ts-expect-error 82 | let v = e.currentTarget?.innerText 83 | }) 84 | document.addEventListener('click', function (event) { 85 | //@ts-expect-error 86 | let r = event.target?.body 87 | //@ts-expect-error 88 | let b = event.currentTarget?.body 89 | }) 90 | input?.addEventListener('focus', e => { 91 | //@ts-expect-error 92 | let v = e.currentTarget?.value 93 | //@ts-expect-error 94 | let tv = e.target.value 95 | //@ts-expect-error 96 | let tc = e.target.textContent 97 | }) 98 | input?.addEventListener('input', e => { 99 | //@ts-expect-error 100 | let v = e.currentTarget?.value 101 | //@ts-expect-error 102 | let tv = e.target.value 103 | //@ts-expect-error 104 | let tc = e.target.textContent 105 | //@ts-expect-error 106 | e.inputType?.indexOf('a') 107 | }) 108 | txtar?.addEventListener('input', e => { 109 | //@ts-expect-error 110 | let v = e.currentTarget?.value 111 | //@ts-expect-error 112 | let tv = e.target.value 113 | //@ts-expect-error 114 | let tc = e.target.textContent 115 | //@ts-expect-error 116 | e.inputType.indexOf('a') 117 | }) 118 | } 119 | 120 | window.addEventListener('click', e => { 121 | if (e.target) { 122 | if (e.isTrusted === true) { 123 | e.target // is Element 124 | } 125 | 126 | if (e.target instanceof Window) { 127 | e.target // is Window 128 | } 129 | else { 130 | e.target // is Node 131 | } 132 | } 133 | }) -------------------------------------------------------------------------------- /tests_origin/ecma.ts: -------------------------------------------------------------------------------- 1 | //@ts-check 2 | 3 | /// TESTS ORIGIN FEATURES (REPEATS TESTS ON ORIGIN TS FOR CHECKING OF FIXING ACCORDING FEATURES): 4 | 5 | 6 | /// Array.map 7 | 8 | 9 | const a = [1, 2, 3] as const; 10 | let arr = a.map(r => r + '') 11 | let item = arr[3] 12 | 13 | 14 | /// Array.indexOf 15 | 16 | 17 | function getIndex(arg: number) { 18 | //@ts-expect-error 19 | var index = a.indexOf(arg) 20 | } 21 | 22 | 23 | 24 | 25 | /// Array.isArray 26 | 27 | 28 | function checkIsReadonlyArray(a: { a: 1 } | ReadonlyArray) { 29 | if (Array.isArray(a)) { 30 | a[0] = 1 31 | a.forEach(item => item.f()) 32 | } 33 | else { 34 | //@ts-expect-error 35 | a.a 36 | } 37 | } 38 | 39 | function checkIsArray(a: { a: 1 } | Array) { 40 | if (Array.isArray(a)) { 41 | a[0] = 1 42 | //@ts-expect-error 43 | a.forEach(item => item.f()) 44 | } 45 | else a.a 46 | } 47 | 48 | 49 | 50 | 51 | /// Object.assign 52 | 53 | const o1 = { a: 1, b: 1 }; 54 | const o2 = { b: '', c: 1 } 55 | 56 | //@ts-expect-error 57 | Object.assign(o1, o2).b = 'ok' 58 | 59 | 60 | 61 | 62 | /// Object.defineProperty 63 | 64 | Object.defineProperty(1, "name", {}) 65 | const r = Object.defineProperty({ a: 1 }, "name", { 66 | value: 1, 67 | }); 68 | 69 | let n: number = r.a 70 | //@ts-expect-error 71 | let v = r.name; 72 | 73 | 74 | /// Object.defineProperties 75 | 76 | 77 | { 78 | 79 | const rs = Object.defineProperties({ a: 1 }, { 80 | d: { 81 | value: 1, 82 | writable: true 83 | } 84 | }); 85 | 86 | let na: number = rs.a 87 | //@ts-expect-error: d does not exists! 88 | let nd: number = rs.d 89 | } 90 | 91 | 92 | 93 | /// Object.create: 94 | 95 | { 96 | let o = Object.create(null) 97 | if (o === 1) { } 98 | } 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | /// Object.keys: 110 | 111 | let k = Object.keys({ a: 1 }) 112 | function succesFunc(arg: string) { 113 | k[0] = arg; 114 | } 115 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | /* Visit https://aka.ms/tsconfig.json to read more about this file */ 4 | 5 | /* Projects */ 6 | // "incremental": true, /* Enable incremental compilation */ 7 | // "composite": true, /* Enable constraints that allow a TypeScript project to be used with project references. */ 8 | // "tsBuildInfoFile": "./", /* Specify the folder for .tsbuildinfo incremental compilation files. */ 9 | // "disableSourceOfProjectReferenceRedirect": true, /* Disable preferring source files instead of declaration files when referencing composite projects */ 10 | // "disableSolutionSearching": true, /* Opt a project out of multi-project reference checking when editing. */ 11 | // "disableReferencedProjectLoad": true, /* Reduce the number of projects loaded automatically by TypeScript. */ 12 | 13 | /* Language and Environment */ 14 | "target": "es2017", /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */ 15 | // "lib": [], /* Specify a set of bundled library declaration files that describe the target runtime environment. */ 16 | // "jsx": "preserve", /* Specify what JSX code is generated. */ 17 | // "experimentalDecorators": true, /* Enable experimental support for TC39 stage 2 draft decorators. */ 18 | // "emitDecoratorMetadata": true, /* Emit design-type metadata for decorated declarations in source files. */ 19 | // "jsxFactory": "", /* Specify the JSX factory function used when targeting React JSX emit, e.g. 'React.createElement' or 'h' */ 20 | // "jsxFragmentFactory": "", /* Specify the JSX Fragment reference used for fragments when targeting React JSX emit e.g. 'React.Fragment' or 'Fragment'. */ 21 | // "jsxImportSource": "", /* Specify module specifier used to import the JSX factory functions when using `jsx: react-jsx*`.` */ 22 | // "reactNamespace": "", /* Specify the object invoked for `createElement`. This only applies when targeting `react` JSX emit. */ 23 | // "noLib": true, /* Disable including any library files, including the default lib.d.ts. */ 24 | // "useDefineForClassFields": true, /* Emit ECMAScript-standard-compliant class fields. */ 25 | 26 | /* Modules */ 27 | "module": "commonjs", /* Specify what module code is generated. */ 28 | // "rootDir": "./", /* Specify the root folder within your source files. */ 29 | // "moduleResolution": "node", /* Specify how TypeScript looks up a file from a given module specifier. */ 30 | // "baseUrl": "./", /* Specify the base directory to resolve non-relative module names. */ 31 | // "paths": {}, /* Specify a set of entries that re-map imports to additional lookup locations. */ 32 | // "rootDirs": [], /* Allow multiple folders to be treated as one when resolving modules. */ 33 | "typeRoots": [ 34 | "./node_modules/@types" 35 | ], /* Specify multiple folders that act like `./node_modules/@types`. */ 36 | // "types": [ 37 | // "./sources/utils/index.ts", 38 | // ], /* Specify type package names to be included without being referenced in a source file. */ 39 | // "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */ 40 | // "resolveJsonModule": true, /* Enable importing .json files */ 41 | // "noResolve": true, /* Disallow `import`s, `require`s or ``s from expanding the number of files TypeScript should add to a project. */ 42 | 43 | /* JavaScript Support */ 44 | "allowJs": true, /* Allow JavaScript files to be a part of your program. Use the `checkJS` option to get errors from these files. */ 45 | // "checkJs": true, /* Enable error reporting in type-checked JavaScript files. */ 46 | // "maxNodeModuleJsDepth": 1, /* Specify the maximum folder depth used for checking JavaScript files from `node_modules`. Only applicable with `allowJs`. */ 47 | 48 | /* Emit */ 49 | // "declaration": true, /* Generate .d.ts files from TypeScript and JavaScript files in your project. */ 50 | // "declarationMap": true, /* Create sourcemaps for d.ts files. */ 51 | // "emitDeclarationOnly": true, /* Only output d.ts files and not JavaScript files. */ 52 | // "sourceMap": true, /* Create source map files for emitted JavaScript files. */ 53 | // "outFile": "./", /* Specify a file that bundles all outputs into one JavaScript file. If `declaration` is true, also designates a file that bundles all .d.ts output. */ 54 | "outDir": "./dist", /* Specify an output folder for all emitted files. */ 55 | // "removeComments": true, /* Disable emitting comments. */ 56 | // "noEmit": true, /* Disable emitting files from a compilation. */ 57 | // "importHelpers": true, /* Allow importing helper functions from tslib once per project, instead of including them per-file. */ 58 | // "importsNotUsedAsValues": "remove", /* Specify emit/checking behavior for imports that are only used for types */ 59 | // "downlevelIteration": true, /* Emit more compliant, but verbose and less performant JavaScript for iteration. */ 60 | // "sourceRoot": "", /* Specify the root path for debuggers to find the reference source code. */ 61 | // "mapRoot": "", /* Specify the location where debugger should locate map files instead of generated locations. */ 62 | // "inlineSourceMap": true, /* Include sourcemap files inside the emitted JavaScript. */ 63 | // "inlineSources": true, /* Include source code in the sourcemaps inside the emitted JavaScript. */ 64 | // "emitBOM": true, /* Emit a UTF-8 Byte Order Mark (BOM) in the beginning of output files. */ 65 | // "newLine": "crlf", /* Set the newline character for emitting files. */ 66 | // "stripInternal": true, /* Disable emitting declarations that have `@internal` in their JSDoc comments. */ 67 | // "noEmitHelpers": true, /* Disable generating custom helper functions like `__extends` in compiled output. */ 68 | // "noEmitOnError": true, /* Disable emitting files if any type checking errors are reported. */ 69 | // "preserveConstEnums": true, /* Disable erasing `const enum` declarations in generated code. */ 70 | // "declarationDir": "./", /* Specify the output directory for generated declaration files. */ 71 | // "preserveValueImports": true, /* Preserve unused imported values in the JavaScript output that would otherwise be removed. */ 72 | 73 | /* Interop Constraints */ 74 | // "isolatedModules": true, /* Ensure that each file can be safely transpiled without relying on other imports. */ 75 | // "allowSyntheticDefaultImports": true, /* Allow 'import x from y' when a module doesn't have a default export. */ 76 | "esModuleInterop": true, /* Emit additional JavaScript to ease support for importing CommonJS modules. This enables `allowSyntheticDefaultImports` for type compatibility. */ 77 | // "preserveSymlinks": true, /* Disable resolving symlinks to their realpath. This correlates to the same flag in node. */ 78 | "forceConsistentCasingInFileNames": true, /* Ensure that casing is correct in imports. */ 79 | 80 | /* Type Checking */ 81 | "strict": true, /* Enable all strict type-checking options. */ 82 | // "noImplicitAny": true, /* Enable error reporting for expressions and declarations with an implied `any` type.. */ 83 | // "strictNullChecks": true, /* When type checking, take into account `null` and `undefined`. */ 84 | // "strictFunctionTypes": true, /* When assigning functions, check to ensure parameters and the return values are subtype-compatible. */ 85 | // "strictBindCallApply": true, /* Check that the arguments for `bind`, `call`, and `apply` methods match the original function. */ 86 | // "strictPropertyInitialization": true, /* Check for class properties that are declared but not set in the constructor. */ 87 | // "noImplicitThis": true, /* Enable error reporting when `this` is given the type `any`. */ 88 | // "useUnknownInCatchVariables": true, /* Type catch clause variables as 'unknown' instead of 'any'. */ 89 | // "alwaysStrict": true, /* Ensure 'use strict' is always emitted. */ 90 | // "noUnusedLocals": true, /* Enable error reporting when a local variables aren't read. */ 91 | // "noUnusedParameters": true, /* Raise an error when a function parameter isn't read */ 92 | // "exactOptionalPropertyTypes": true, /* Interpret optional property types as written, rather than adding 'undefined'. */ 93 | // "noImplicitReturns": true, /* Enable error reporting for codepaths that do not explicitly return in a function. */ 94 | // "noFallthroughCasesInSwitch": true, /* Enable error reporting for fallthrough cases in switch statements. */ 95 | // "noUncheckedIndexedAccess": true, /* Include 'undefined' in index signature results */ 96 | // "noImplicitOverride": true, /* Ensure overriding members in derived classes are marked with an override modifier. */ 97 | // "noPropertyAccessFromIndexSignature": true, /* Enforces using indexed accessors for keys declared using an indexed type */ 98 | // "allowUnusedLabels": true, /* Disable error reporting for unused labels. */ 99 | // "allowUnreachableCode": true, /* Disable error reporting for unreachable code. */ 100 | 101 | /* Completeness */ 102 | "skipDefaultLibCheck": false, /* Skip type checking .d.ts files that are included with TypeScript. */ 103 | "skipLibCheck": false /* Skip type checking all .d.ts files. */ 104 | }, 105 | "exclude": [ 106 | "./node_modules/**/*" 107 | ], 108 | "include": [ 109 | "./sources/**/*", 110 | "./tests/*.ts", 111 | "sources/document/_index.d.ts", 112 | "sources/document/_$research.ts" // "rollup.config.js" 113 | ] 114 | } 115 | --------------------------------------------------------------------------------