diff --git a/README.md b/README.md index 28929a9..c5d84ae 100644 --- a/README.md +++ b/README.md @@ -1,110 +1,69 @@ # TypeScript Baseline Lib Generator -This project generates `baseline.d.ts`. This TypeScript lib contains declarations for JavaScript features that are [Baseline Widely available](https://web.dev/baseline). +Catch JavaScript API calls that are too new for your Baseline target. `typescript-baseline-lib` gives your editor and TypeScript compiler a set of built-in types selected by [Baseline](https://web.dev/baseline) browser support data. -The generator currently classifies `javascript.builtins.*` and the `arguments` object from `web-features`. +TypeScript's `ESNext` lib can accept APIs that your supported browsers cannot run. This package selects declarations from TypeScript using per-API data from `web-features`. By default, it includes Baseline Widely available APIs: those supported across the Baseline core browsers for at least 30 months. -## Best-practice setup +In the October 2026 snapshot, TypeScript accepts `.at()` but reports an error for `Promise.try()`: -TypeScript does not yet include `"baseline"` as a built-in `lib`. Install this package and the supported TypeScript major: +```ts +["a", "b"].at(-1); +Promise.try(() => 42); +``` + +Use it to check browser code or shared JavaScript modules before shipping. It checks API types; it does not transform syntax or load polyfills. + +## Get started + +The package supports TypeScript 6 and 7. Install it with TypeScript: ```sh npm install --save-dev typescript@^7 typescript-baseline-lib ``` -Configure the package as the complete global lib: +For JavaScript built-ins without browser or Node.js globals, start with this `tsconfig.json`: ```json { "compilerOptions": { "noLib": true, "strict": true, + "noEmit": true, "types": ["typescript-baseline-lib"] } } ``` -Run the compiler: +Run the check: ```sh -npx tsc --noEmit +npx tsc ``` -With this configuration, TypeScript accepts supported JavaScript APIs that are Baseline Widely available. TypeScript reports APIs outside this target as errors. - -Examples include `Promise.try` and `Intl.Segmenter` before they reach this Baseline status. The project goal is first-class `--lib baseline` support in TypeScript. - -For more configurations, read the [Usage Guide](docs/USAGE.md). - -This package replaces the default TypeScript libs. Do not set `compilerOptions.lib`. Do not combine this package with standard `es*` libs. - -If your project needs other ambient type packages, add them to `types`. Some packages require runtime APIs outside the selected Baseline target. - -The generator preserves audited declarations that support TypeScript. These declarations do not represent runtime APIs. - -The generator does not add unavailable runtime APIs to support third-party packages. - -## Allow a polyfilled feature - -If the runtime loads an audited polyfill, add its generated `web-features` entry after the base package. For example, core-js can provide `Promise.try`: - -```ts -import "core-js/proposals/promise-try"; -``` - -```json -{ - "compilerOptions": { - "noLib": true, - "types": [ - "typescript-baseline-lib", - "typescript-baseline-lib/allow/promise-try" - ] - } -} -``` - -Only entries in `registry/allowlist.json` are public. The registry defines permanent public paths. - -Published entry paths remain valid. After all registered compat keys become Baseline Widely available, the entry refers to the base package. - -The generator rejects features with `baselineStatus: false`. - -## Target a Baseline year - -Baseline year targets contain all JavaScript features that became Baseline Newly available by the end of a completed calendar year. For example, Baseline 2024 includes `Promise.withResolvers`: - -```json -{ - "compilerOptions": { - "noLib": true, - "types": ["typescript-baseline-lib/year/2024"] - } -} -``` +This package replaces TypeScript's standard JavaScript libs. Do not combine it with `lib` or standard `es*` declarations. For browser globals, an existing tsconfig, or a separate CI check, follow the [Usage Guide](docs/USAGE.md). -The generator creates year entry points from the `baselineLowDate` of each compat row. Each entry is a complete alternative to the rolling base. +## Choose a target -The generator omits the current year until that year is complete. The first generated year is 2020. +| Target | Use it when | +| --- | --- | +| `typescript-baseline-lib` | You want the Widely available snapshot in the installed package. | +| `typescript-baseline-lib/year/2024` | You want APIs that became Newly available by the end of 2024. | +| `typescript-baseline-lib/allow/promise-try` | You load a suitable polyfill and need its types alongside the root target. | -The generator cannot close the TypeScript declaration graphs for 2015 through 2019. Those graphs require symbols from later years. +Year targets are complete alternatives to the root target. Choose one completed year from 2020 onward; do not combine it with the root or an `allow/*` entry. A year fixes the cutoff, while the installed package fixes the declaration snapshot. Pin the package version and commit your lockfile for repeatable checks. -This limit belongs to the implementation, not the Baseline specification. +An `allow/*` entry adds types only. Load the matching polyfill before using the API. The [allowlist](registry/allowlist.json) defines the public entries, and their paths remain valid after an API becomes Widely available. See the [polyfill example](docs/USAGE.md#i-polyfill-one-api-outside-the-rolling-target) for setup. -Do not combine a `year/*` entry point with the base package or an `allow/*` entry point. Each year file is a complete historical target. +## Scope -An `allow/*` entry applies only to the current rolling base. The generation report lists declaration-backed compat keys and managed upstream gaps. +The package covers JavaScript built-ins and the `arguments` object. It does not filter DOM or Worker APIs, check syntax support, or prove that code will run in every browser. Additional ambient declarations can expose APIs outside the selected target. -The report is in `derived/current/generation.json`. The generator does not create declarations for behavior that TypeScript cannot model. +The generator can only select APIs modeled by TypeScript declarations. Its [generation report](derived/current/generation.json) records declaration coverage and known gaps. Helper types needed by TypeScript are kept separately from runtime API availability. -Year boundaries apply to runtime JavaScript APIs. The pinned TypeScript toolchain supplies helper declarations. +For syntax and Web API checks, use [eslint-plugin-baseline-js](https://github.com/3ru/eslint-plugin-baseline-js) alongside this package. -These helper declarations are not historical runtime features. +## Work on the generator -## Current contract +This repository generates the npm package from pinned TypeScript and `web-features` inputs. The same inputs produce the same declarations, and the tests check both supported TypeScript majors and integration with the pinned upstream compiler. -- The public targets include the rolling base, completed cumulative years from 2020, and audited `allow/*` additions. -- The scope includes `javascript.builtins.*` and the `arguments` object. -- DOM, Web Worker, syntax, grammar, statements, and operators are outside the scope. -- `registry/compat-management.json` manages special compat rows and records a source URL for each row. -- The repository stores one rolling dataset and one set of derived artifacts. Git stores the history. +The long-term goal is native `--lib baseline` support in TypeScript. For the current package, use the configuration above. See [Contributing](CONTRIBUTING.md) to run the generator and tests, or [Operations](docs/OPERATIONS.md) to update its inputs. diff --git a/deploy/readmes/baseline.md b/deploy/readmes/baseline.md index 7731154..85bedaf 100644 --- a/deploy/readmes/baseline.md +++ b/deploy/readmes/baseline.md @@ -1,117 +1,75 @@ # {{PACKAGE_NAME}} -This package contains generated `baseline` declarations for TypeScript. +Catch JavaScript API calls that are too new for your Baseline target. This package gives your editor and TypeScript compiler a set of built-in types selected by [Baseline](https://web.dev/baseline) browser support data. -The [`TypeScript-Baseline-lib-generator`](https://github.com/3ru/TypeScript-Baseline-lib-generator) repository produces this package. It combines TypeScript declarations for JavaScript features that are [Baseline Widely available](https://web.dev/baseline). +TypeScript's `ESNext` lib can accept APIs that your supported browsers cannot run. This package selects declarations from TypeScript using per-API data from `web-features`. By default, it includes Baseline Widely available APIs: those supported across the Baseline core browsers for at least 30 months. -Current snapshot: +In the October 2026 snapshot, TypeScript accepts `.at()` but reports an error for `Promise.try()`: -- Supported TypeScript versions: `{{TYPESCRIPT_PEER_DEPENDENCY_RANGE}}` -- Baseline date: `{{BASELINE_DATE}}` -- TypeScript package: `{{TYPESCRIPT_VERSION}}` -- web-features package: `{{WEB_FEATURES_VERSION}}` -- web-features gitHead: `{{WEB_FEATURES_GIT_HEAD}}` -- Included compat rows: `{{INCLUDED_COMPAT_COUNT}}` -- Selected declaration units: `{{SELECTED_UNIT_COUNT}}` -- Transformed units: `{{TRANSFORMED_UNIT_COUNT}}` +```ts +["a", "b"].at(-1); +Promise.try(() => 42); +``` + +Use it to check browser code or shared JavaScript modules before shipping. It checks API types; it does not transform syntax or load polyfills. -## Best-practice setup +## Get started -TypeScript does not yet include `"baseline"` as a built-in `lib`. Install this package and the supported TypeScript major: +The package supports TypeScript 6 and 7. Install it with TypeScript: ```sh npm install --save-dev typescript@^7 {{PACKAGE_NAME}} ``` -This package also supports TypeScript 6 within `{{TYPESCRIPT_PEER_DEPENDENCY_RANGE}}`. TypeScript is an optional peer dependency. - -Tools can read the same snapshot facts from `{{PACKAGE_NAME}}/snapshot.json`. - -Configure the package as the complete global lib: +For JavaScript built-ins without browser or Node.js globals, start with this `tsconfig.json`: ```json { "compilerOptions": { "noLib": true, "strict": true, + "noEmit": true, "types": ["{{PACKAGE_NAME}}"] } } ``` -Run the compiler: +Run the check: ```sh -npx tsc --noEmit -``` - -With this configuration, TypeScript accepts supported JavaScript APIs that are Baseline Widely available. TypeScript reports APIs outside this target as errors. - -This package replaces the default TypeScript libs. Do not set `compilerOptions.lib`. Do not combine this package with standard `es*` libs. - -If your project needs other ambient type packages, add them to `types`. Some packages require runtime APIs outside the selected Baseline target. - -The package preserves declarations that support TypeScript. These declarations do not represent runtime APIs. - -The package does not expose unavailable runtime APIs to support third-party packages. - -## Allow a polyfilled feature - -If the runtime loads an audited polyfill, add its generated `web-features` entry after the base package. For example, core-js can provide `Promise.try`: - -```ts -import "core-js/proposals/promise-try"; -``` - -```json -{ - "compilerOptions": { - "noLib": true, - "types": [ - "{{PACKAGE_NAME}}", - "{{PACKAGE_NAME}}/allow/promise-try" - ] - } -} +npx tsc ``` -Only audited entries are public. Published entry paths remain valid. - -After all compat keys become Baseline Widely available, the entry refers to the base package. +This package replaces TypeScript's standard JavaScript libs. Do not combine it with `lib` or standard `es*` declarations. For browser globals, an existing tsconfig, or a separate CI check, follow the [Usage Guide](https://github.com/3ru/TypeScript-Baseline-lib-generator/blob/main/docs/USAGE.md). -The generator rejects features with `baselineStatus: false`. +## Choose a target -## Target a Baseline year +| Target | Use it when | +| --- | --- | +| `{{PACKAGE_NAME}}` | You want the Widely available snapshot in the installed package. | +| `{{PACKAGE_NAME}}/year/2024` | You want APIs that became Newly available by the end of 2024. | +| `{{PACKAGE_NAME}}/allow/promise-try` | You load a suitable polyfill and need its types alongside the root target. | -Baseline year targets contain all JavaScript features that became Baseline Newly available by the end of a completed calendar year. For example, Baseline 2024 includes `Promise.withResolvers`: - -```json -{ - "compilerOptions": { - "noLib": true, - "types": ["{{PACKAGE_NAME}}/year/2024"] - } -} -``` +Year targets are complete alternatives to the root target. Choose one completed year from 2020 onward; do not combine it with the root or an `allow/*` entry. A year fixes the cutoff, while the installed package fixes the declaration snapshot. Pin the package version and commit your lockfile for repeatable checks. -The generator creates year entry points from the `baselineLowDate` of each compat row. Each entry is a complete alternative to the rolling base. +An `allow/*` entry adds types only. Load the matching polyfill before using the API. The [allowlist](https://github.com/3ru/TypeScript-Baseline-lib-generator/blob/main/registry/allowlist.json) defines the public entries, and their paths remain valid after an API becomes Widely available. See the [polyfill example](https://github.com/3ru/TypeScript-Baseline-lib-generator/blob/main/docs/USAGE.md#i-polyfill-one-api-outside-the-rolling-target) for setup. -The generator omits the current year until that year is complete. Targets before 2020 are not available because their declaration graphs require later symbols. +## Scope -Do not combine a `year/*` entry point with the base package or an `allow/*` entry point. Each year file is a complete historical target. +The package covers JavaScript built-ins and the `arguments` object. It does not filter DOM or Worker APIs, check syntax support, or prove that code will run in every browser. Additional ambient declarations can expose APIs outside the selected target. -An `allow/*` entry applies only to the current rolling base. `reports/generation.json` lists declaration-backed compat keys and managed upstream gaps. +The generator can only select APIs modeled by TypeScript declarations. The package's `reports/generation.json` records declaration coverage and known gaps. Helper types needed by TypeScript are kept separately from runtime API availability. -The generator does not create declarations for behavior that TypeScript cannot model. +For syntax and Web API checks, use [eslint-plugin-baseline-js](https://github.com/3ru/eslint-plugin-baseline-js) alongside this package. -Year boundaries apply to runtime JavaScript APIs. The pinned TypeScript toolchain supplies helper declarations. +## Snapshot -These helper declarations are not historical runtime features. +- Supported TypeScript versions: `{{TYPESCRIPT_PEER_DEPENDENCY_RANGE}}` +- Baseline date: `{{BASELINE_DATE}}` +- TypeScript declarations: `{{TYPESCRIPT_VERSION}}` +- web-features package: `{{WEB_FEATURES_VERSION}}` +- Included compat rows: `{{INCLUDED_COMPAT_COUNT}}` -## Notes +Snapshot data and the web-features source revision are also available in `{{PACKAGE_NAME}}/snapshot.json`. TypeScript is an optional peer dependency. -- The base public surface is one `baseline` lib. -- Audited `allow/*` entry points add declarations for explicitly polyfilled APIs. -- Completed cumulative year entry points are complete alternatives to the base lib. -- The current scope includes `javascript.builtins.*` and the `arguments` object. -- The npm `typescript` package supplies the declarations. The package preserves the Microsoft license notice. +The [generator repository](https://github.com/3ru/TypeScript-Baseline-lib-generator) contains the source and contribution guide. Declarations come from TypeScript, and the package preserves Microsoft's license notice. diff --git a/docs/USAGE.md b/docs/USAGE.md index 1a47a2d..94ab8bf 100644 --- a/docs/USAGE.md +++ b/docs/USAGE.md @@ -1,16 +1,12 @@ # Usage Guide -Copy these configurations for common `typescript-baseline-lib` use cases. - -Use TypeScript 7 for new projects. This package also supports TypeScript 6 for tools that require its programmatic API. +Use `typescript-baseline-lib` to check JavaScript built-in APIs against your Baseline policy in the editor or CI. The examples below work with TypeScript 6 and 7; the install commands use TypeScript 7 unless noted. ## Before you choose a configuration -- Set `noLib` to `true`. TypeScript then ignores `lib`. -- Choose one complete target. Use the rolling root package or one `year/*` entry. -- If the runtime loads the matching polyfill, add an `allow/*` entry to the rolling root package. -- Do not enable `skipLibCheck`. This option hides declaration conflicts and weakens the compatibility gate. -- This package filters JavaScript built-in declarations by Baseline status. It does not transform syntax, install polyfills, or filter DOM APIs. +Choose one complete target: the rolling root package or one `year/*` entry. Set `noLib` to `true` so TypeScript uses that target instead of its standard libraries. Do not combine it with `lib` or standard `es*` declarations, and keep `skipLibCheck` disabled so declaration conflicts remain visible. If you extend another configuration, use the [separate CI gate](#i-want-a-separate-ci-gate) example to clear an inherited `lib` setting. + +These declarations control which built-in APIs TypeScript knows about. The compiler's `target` option controls emitted JavaScript syntax; it does not make runtime APIs available. This package does not transform syntax, load polyfills, or filter DOM APIs. ## I want the current Baseline Widely available target @@ -40,7 +36,7 @@ Run the compiler: npx tsc -p tsconfig.json ``` -Each package release contains one rolling snapshot. If your compatibility contract must remain fixed, select a year target. +Each package release contains a Baseline snapshot, so updating the package can change the APIs accepted by the rolling target. Use a year target for a fixed availability cutoff, and pin the package version and keep your lockfile for reproducible checks. ## I want a browser application with DOM types @@ -64,9 +60,7 @@ Configure both type packages: } ``` -`@types/web` supplies `document`, `Window`, and other browser declarations. This package does not filter those DOM declarations. - -The Baseline gate applies only to the generated JavaScript built-ins. +`@types/web` supplies `document`, `Window`, and other browser declarations. Those declarations are not filtered by this package: the Baseline check still applies only to the generated JavaScript built-ins. Keep your existing JSX settings if the project uses `.tsx` files. ## I want a separate CI gate @@ -76,8 +70,10 @@ Keep the normal `tsconfig.json`. Create `tsconfig.baseline.json` for the Baselin { "extends": "./tsconfig.json", "compilerOptions": { + "lib": null, "noLib": true, "noEmit": true, + "skipLibCheck": false, "types": ["typescript-baseline-lib"] }, "include": ["src/**/*.ts"] @@ -100,9 +96,7 @@ Run the gate: npm run check:baseline ``` -The child configuration replaces the inherited ambient `types`. The `noLib` option disables each inherited standard `lib`. - -For browser source, install `@types/web`. Then use `"types": ["typescript-baseline-lib", "web"]`. +The child configuration replaces the inherited `types` and clears `lib` with `null`. Without that override, an inherited `lib` conflicts with `noLib` and TypeScript reports TS5053. Setting `skipLibCheck` to `false` also keeps declaration checking enabled when the parent configuration disables it. For browser source, install `@types/web` and use `"types": ["typescript-baseline-lib", "web"]`. ## I want a shared package for browsers and Node.js @@ -112,23 +106,21 @@ Apply the Baseline gate only to platform-neutral source: { "extends": "./tsconfig.json", "compilerOptions": { + "lib": null, "noLib": true, "noEmit": true, + "skipLibCheck": false, "types": ["typescript-baseline-lib"] }, "include": ["src/shared/**/*.ts"] } ``` -Do not add `dom`, `web`, or `node` globals to this shared-source gate. Use separate build configurations for browser and Node.js entry points. - -Do not add `@types/node` to this shared-source gate. Node declarations can require runtime surfaces before they reach the selected target. - -Examples include `Disposable` and `Float16Array`. +Keep browser and Node.js globals out of this shared-source check, and use separate configurations for platform-specific entry points. Node declarations can require APIs outside the selected Baseline target, such as `Disposable` and `Float16Array`. Baseline describes browser availability; it does not certify support in a particular Node.js version. ## I want a fixed Baseline year -Use one complete cumulative year entry: +Use one complete cumulative year entry to check APIs that became Baseline Newly available by the end of that year: ```json { @@ -142,7 +134,7 @@ Use one complete cumulative year entry: } ``` -Do not combine a `year/*` entry with the root package or an `allow/*` entry. The package supplies completed year targets from 2020. +The package supplies completed year targets from 2020. Each year entry replaces the rolling target, so do not combine it with the root package or an `allow/*` entry. The cutoff stays fixed, but later package releases can correct compatibility data or declarations; pin the package version when the exact output must stay unchanged. ## I polyfill one API outside the rolling target @@ -161,7 +153,7 @@ import "core-js/proposals/promise-try"; const result = Promise.try(() => 42); ``` -Then add its audited declaration entry: +Then add the matching declaration entry: ```json { @@ -177,9 +169,7 @@ Then add its audited declaration entry: } ``` -An `allow/*` entry changes type availability only. It does not install or load a runtime polyfill. - -The permanent allowlist in the repository defines the public entries. +An `allow/*` entry adds types to the rolling target; it does not install or load a polyfill. Your application must provide the API at runtime. Choose an entry from the [public allowlist](../registry/allowlist.json); those paths stay valid when an API later joins the rolling target. ## I want Vite to use the same policy @@ -195,11 +185,9 @@ export default defineConfig({ }); ``` -Combine this setting with the browser TypeScript configuration. Vite transforms syntax, but it does not usually polyfill JavaScript APIs. +Combine this setting with the browser TypeScript configuration. Vite's build target handles syntax; it does not add polyfills for calls such as `Promise.try`. Vite freezes its Baseline browser snapshot for each major release, while this package updates its root entry in separate releases. The policy names align, but the snapshots may differ. -Vite freezes its Baseline browser snapshot for each major release. This package updates its root entry through separate dataset and package releases. - -## I want Browserslist and TypeScript to use the same target +## I want a Baseline policy in Browserslist For a rolling target, add `.browserslistrc`: @@ -217,7 +205,7 @@ baseline 2024 Use it with `"types": ["typescript-baseline-lib/year/2024"]`. -Browserslist supplies target data to compatible build and CSS tools. The TypeScript package separately limits the JavaScript built-in declaration surface. +Browserslist selects browsers for compatible build and CSS tools, while this package selects JavaScript built-in declarations. Their data is updated separately, so a matching policy name does not guarantee an identical snapshot. ## I must use TypeScript 6 @@ -231,12 +219,14 @@ Use the same `noLib` and `types` values from the other configurations. This conf ## I want ESLint to enforce the same Baseline -Install [`eslint-plugin-baseline-js`](https://github.com/3ru/eslint-plugin-baseline-js). This plugin covers syntax and Web APIs that a TypeScript lib cannot model. +Use [`eslint-plugin-baseline-js`](https://github.com/3ru/eslint-plugin-baseline-js) for additional checks on syntax and Web APIs. It complements the built-in API checks provided by this package: ```sh npm install --save-dev eslint eslint-plugin-baseline-js ``` +Add the plugin to your ESLint flat configuration. This minimal example works for JavaScript; TypeScript files also need your usual TypeScript parser and file patterns. Keep that setup when adding these entries. + ```js // eslint.config.mjs import baselineJs from "eslint-plugin-baseline-js"; @@ -250,7 +240,7 @@ export default [ ]; ``` -For the same fixed year, set `available: 2024` and use `typescript-baseline-lib/year/2024`. +For a matching year policy, set `available: 2024` and use `typescript-baseline-lib/year/2024`. The plugin and this package have separate data releases and coverage, so they may not report exactly the same features. ## I want to inspect the loaded TypeScript files @@ -260,7 +250,7 @@ Run: npx tsc -p tsconfig.baseline.json --explainFiles ``` -The output must include `typescript-baseline-lib`. It must not include standard TypeScript `lib.es*.d.ts` files. +The output should include `typescript-baseline-lib` and exclude standard TypeScript `lib.es*.d.ts` files. If a missing-API error suggests adding an `es*` library, that would broaden the declarations beyond your selected target. Choose an API within the target or provide a suitable polyfill and allow entry instead. ## References