├── .changeset ├── README.md └── config.json ├── .codesandbox └── ci.json ├── .commitlintrc ├── .eslintignore ├── .eslintrc.cjs ├── .github └── workflows │ ├── ci.yml │ ├── codeql.yml │ └── release.yml ├── .gitignore ├── .lintstagedrc.cjs ├── .prettierignore ├── .prettierrc ├── .remarkrc ├── .renovaterc ├── .simple-git-hooks.cjs ├── CHANGELOG.md ├── LICENSE ├── README.md ├── babel.config.cjs ├── jest.config.js ├── package.json ├── scripts └── is-record-tuple-supported.cjs ├── src ├── index.ts ├── shim.d.ts ├── tsconfig.json ├── utils.ts └── v8intrinsic.ts ├── test ├── __snapshots__ │ ├── destructuring-private.spec.ts.snap │ ├── do-expressions.spec.ts.snap │ ├── duplicate-named-capturing-groups-regex.spec.ts.snap │ ├── import-defer.spec.ts.snap │ ├── import-wasm-source.spec.ts.snap │ ├── partial-application.spec.ts.snap │ ├── pipeline-operator.spec.ts.snap │ ├── record-and-tuple.spec.ts.snap │ ├── regexp-modifiers.spec.ts.snap │ ├── throw-expressions.spec.ts.snap │ └── v8intrinsic.spec.ts.snap ├── async-do-expressions.spec.ts ├── async-do-expressions.ts ├── declare-field.spec.ts ├── declare-field.ts ├── destructuring-private.spec.ts ├── destructuring-private.ts ├── do-expressions.spec.ts ├── do-expressions.ts ├── duplicate-named-capturing-groups-regex.spec.ts ├── duplicate-named-capturing-groups-regex.ts ├── function-bind.spec.ts ├── function-bind.ts ├── function-sent.spec.ts ├── function-sent.ts ├── helpers.ts ├── import-defer.cts ├── import-defer.spec.ts ├── import-wasm-source.spec.ts ├── import-wasm-source.ts ├── optional-chaining-assign.spec.ts ├── optional-chaining-assign.ts ├── partial-application.spec.ts ├── partial-application.ts ├── pipeline-operator.spec.ts ├── pipeline-operator.ts ├── record-and-tuple.spec.ts ├── record-and-tuple.ts ├── regexp-modifiers.spec.ts ├── regexp-modifiers.ts ├── throw-expressions.spec.ts ├── throw-expressions.ts ├── v8intrinsic.cjs └── v8intrinsic.spec.ts ├── tsconfig.json └── yarn.lock /.changeset/README.md: -------------------------------------------------------------------------------- 1 | # Changesets 2 | 3 | Hello and welcome! This folder has been automatically generated by `@changesets/cli`, a build tool that works 4 | with multi-package repos, or single-package repos to help you version and publish your code. You can 5 | find the full documentation for it [in our repository](https://github.com/changesets/changesets) 6 | 7 | We have a quick list of common questions to get you started engaging with this project in 8 | [our documentation](https://github.com/changesets/changesets/blob/main/docs/common-questions.md) 9 | -------------------------------------------------------------------------------- /.changeset/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://unpkg.com/@changesets/config/schema.json", 3 | "changelog": [ 4 | "@changesets/changelog-github", 5 | { 6 | "repo": "un-ts/babel-preset-proposal-typescript" 7 | } 8 | ], 9 | "commit": false, 10 | "linked": [], 11 | "access": "public", 12 | "baseBranch": "master", 13 | "updateInternalDependencies": "patch", 14 | "ignore": [] 15 | } 16 | -------------------------------------------------------------------------------- /.codesandbox/ci.json: -------------------------------------------------------------------------------- 1 | { 2 | "node": "18", 3 | "sandboxes": [] 4 | } 5 | -------------------------------------------------------------------------------- /.commitlintrc: -------------------------------------------------------------------------------- 1 | { 2 | "extends": [ 3 | "@1stg" 4 | ] 5 | } 6 | -------------------------------------------------------------------------------- /.eslintignore: -------------------------------------------------------------------------------- 1 | coverage 2 | lib 3 | node_modules 4 | CHANGELOG.md 5 | /test/import-defer.cts 6 | /test/v8intrinsic.cjs 7 | !/.github 8 | !/.*.js 9 | -------------------------------------------------------------------------------- /.eslintrc.cjs: -------------------------------------------------------------------------------- 1 | const { 2 | configs, 3 | jest, 4 | js, 5 | json, 6 | jsonc, 7 | test, 8 | ts, 9 | md, 10 | mdx, 11 | yml, 12 | } = require('@1stg/eslint-config/overrides') 13 | 14 | module.exports = { 15 | root: true, 16 | extends: ['@1stg/eslint-config/base'], 17 | overrides: [ 18 | ts[0], 19 | jest, 20 | json, 21 | jsonc, 22 | md, 23 | mdx, 24 | test, 25 | configs, 26 | yml, 27 | { 28 | ...js, 29 | files: 'test/*.{cjs,cts,js,ts}', 30 | rules: { 31 | ...js.rules, 32 | 'no-magic-numbers': 'off', 33 | 'jest/valid-title': 'off', 34 | }, 35 | }, 36 | { 37 | files: [ 38 | 'test/duplicate-named-capturing-groups-regex.ts', 39 | 'test/regexp-modifiers.ts', 40 | ], 41 | rules: { 42 | 'regexp/no-invalid-regexp': 'off', 43 | 'unicorn/better-regex': 'off', 44 | }, 45 | }, 46 | ], 47 | } 48 | -------------------------------------------------------------------------------- /.github/workflows/ci.yml: -------------------------------------------------------------------------------- 1 | name: CI 2 | 3 | on: 4 | - push 5 | - pull_request 6 | 7 | jobs: 8 | ci: 9 | name: Lint and Test with Node.js ${{ matrix.node }} 10 | strategy: 11 | matrix: 12 | node: 13 | - 16 14 | - 18 15 | - 20 16 | runs-on: ubuntu-latest 17 | steps: 18 | - name: Checkout Repo 19 | uses: actions/checkout@v4 20 | 21 | - name: Setup Node.js ${{ matrix.node }} 22 | uses: actions/setup-node@v4 23 | with: 24 | node-version: ${{ matrix.node }} 25 | cache: yarn 26 | 27 | - name: Install Dependencies 28 | run: yarn --frozen-lockfile 29 | 30 | - name: Build, Lint and test 31 | run: yarn run-s test lint 32 | env: 33 | EFF_NO_LINK_RULES: true 34 | PARSER_NO_WATCH: true 35 | 36 | - name: Codecov 37 | uses: codecov/codecov-action@v3 38 | -------------------------------------------------------------------------------- /.github/workflows/codeql.yml: -------------------------------------------------------------------------------- 1 | name: CodeQL 2 | 3 | on: 4 | push: 5 | branches: 6 | - master 7 | pull_request: 8 | branches: 9 | - master 10 | schedule: 11 | - cron: '49 21 * * 0' 12 | 13 | jobs: 14 | analyze: 15 | name: Analyze 16 | runs-on: ubuntu-latest 17 | permissions: 18 | actions: read 19 | contents: read 20 | security-events: write 21 | 22 | strategy: 23 | fail-fast: false 24 | matrix: 25 | language: 26 | - javascript 27 | 28 | steps: 29 | - name: Checkout 30 | uses: actions/checkout@v4 31 | 32 | - name: Initialize CodeQL 33 | uses: github/codeql-action/init@v2 34 | with: 35 | languages: ${{ matrix.language }} 36 | queries: +security-and-quality 37 | 38 | - name: Autobuild 39 | uses: github/codeql-action/autobuild@v2 40 | 41 | - name: Perform CodeQL Analysis 42 | uses: github/codeql-action/analyze@v2 43 | with: 44 | category: '/language:${{ matrix.language }}' 45 | -------------------------------------------------------------------------------- /.github/workflows/release.yml: -------------------------------------------------------------------------------- 1 | name: Release 2 | 3 | on: 4 | push: 5 | branches: 6 | - master 7 | 8 | jobs: 9 | release: 10 | name: Release 11 | runs-on: ubuntu-latest 12 | steps: 13 | - name: Checkout Repo 14 | uses: actions/checkout@v4 15 | with: 16 | # This makes Actions fetch all Git history so that Changesets can generate changelogs with the correct commits 17 | fetch-depth: 0 18 | 19 | - name: Setup Node.js LTS 20 | uses: actions/setup-node@v4 21 | with: 22 | node-version: lts/* 23 | cache: yarn 24 | 25 | - name: Install Dependencies 26 | run: yarn --frozen-lockfile 27 | 28 | - name: Create Release Pull Request or Publish to npm 29 | id: changesets 30 | uses: changesets/action@v1 31 | with: 32 | # This expects you to have a script called release which does a build for your packages and calls changeset publish 33 | publish: yarn release 34 | commit: 'chore: release babel-preset-proposal-typescript' 35 | title: 'chore: release babel-preset-proposal-typescript' 36 | env: 37 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 38 | NPM_TOKEN: ${{ secrets.NPM_TOKEN }} 39 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.log 2 | .*cache 3 | lib 4 | coverage 5 | node_modules 6 | -------------------------------------------------------------------------------- /.lintstagedrc.cjs: -------------------------------------------------------------------------------- 1 | module.exports = require('@1stg/lint-staged') 2 | -------------------------------------------------------------------------------- /.prettierignore: -------------------------------------------------------------------------------- 1 | coverage 2 | lib 3 | CHANGELOG.md 4 | -------------------------------------------------------------------------------- /.prettierrc: -------------------------------------------------------------------------------- 1 | "@1stg/prettier-config/next" 2 | -------------------------------------------------------------------------------- /.remarkrc: -------------------------------------------------------------------------------- 1 | { 2 | "plugins": [ 3 | "@1stg/preset" 4 | ] 5 | } 6 | -------------------------------------------------------------------------------- /.renovaterc: -------------------------------------------------------------------------------- 1 | { 2 | "extends": [ 3 | "github>1stG/configs" 4 | ] 5 | } 6 | -------------------------------------------------------------------------------- /.simple-git-hooks.cjs: -------------------------------------------------------------------------------- 1 | module.exports = require('@1stg/simple-git-hooks') 2 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Changelog 2 | 3 | ## 4.0.0 4 | 5 | ### Major Changes 6 | 7 | - [#167](https://github.com/un-ts/babel-preset-proposal-typescript/pull/167) [`bca62a1`](https://github.com/un-ts/babel-preset-proposal-typescript/commit/bca62a12dd0677aa6766ee6cf18e49d786a4d20c) Thanks [@JounQin](https://github.com/JounQin)! - feat!: bump `@babel/core@^7.23.0` and `typescript@^5.3.0` 8 | 9 | ## 3.0.0 10 | 11 | ### Major Changes 12 | 13 | - [`d0e4cf2`](https://github.com/un-ts/babel-preset-proposal-typescript/commit/d0e4cf219a76aa16e5c2379dedfe6750f7aade7f) Thanks [@JounQin](https://github.com/JounQin)! - feat!: upgrade to `typescript@v4.7`, remove unnecessary plugins 14 | 15 | ### Minor Changes 16 | 17 | - [`d0e4cf2`](https://github.com/un-ts/babel-preset-proposal-typescript/commit/d0e4cf219a76aa16e5c2379dedfe6750f7aade7f) Thanks [@JounQin](https://github.com/JounQin)! - feat: `babel-preset-proposal-typescript` is now a dual (commonjs + ESM) package 18 | 19 | ## 2.2.0 20 | 21 | ### Minor Changes 22 | 23 | - [`c29d8f7`](https://github.com/un-ts/babel-preset-proposal-typescript/commit/c29d8f72e10fbb10e4bfabf37ce54365e31d0a40) Thanks [@JounQin](https://github.com/JounQin)! - feat: disable private-methods for typescript 4.3+ 24 | 25 | ## 2.1.0 26 | 27 | ### Minor Changes 28 | 29 | - [#115](https://github.com/un-ts/babel-preset-proposal-typescript/pull/115) Thanks [@JounQin](https://github.com/JounQin)! 30 | 31 | - [`50d6199`](https://github.com/un-ts/babel-preset-proposal-typescript/commit/50d6199bab3f732f49213cbb0087c6397f82074e) feat: upgrade babel core and plugins 32 | - [`db510c9`](https://github.com/un-ts/babel-preset-proposal-typescript/commit/db510c9504506ce2ab73989a03084605e0d3ef7c) feat: enable async-do-expressions and record-and-tuple proposals 33 | - [`1dd2ff6`](https://github.com/un-ts/babel-preset-proposal-typescript/commit/1dd2ff608bd86684b852dc6cd1d08e47bd4f3543) feat!: change `classLoose` default valule to `false` and presets order 34 | 35 | ## 2.0.3 36 | 37 | ### Patch Changes 38 | 39 | - [#118](https://github.com/un-ts/babel-preset-proposal-typescript/pull/118) [`9330176`](https://github.com/un-ts/babel-preset-proposal-typescript/commit/93301762311301ed0d86a5153d48a008aa3d5a45) Thanks [@JounQin](https://github.com/JounQin)! - refactor: remove unused optional-chaining plugin 40 | 41 | ## [2.0.0](https://github.com/un-ts/babel-preset-proposal-typescript/compare/v1.5.0...v2.0.0) (2021-01-26) 42 | 43 | ### ⚠ BREAKING CHANGES 44 | 45 | - bump babel and typescript, add two proposals 46 | 47 | ### Features 48 | 49 | - bump babel and typescript, add two proposals ([3f18e81](https://github.com/un-ts/babel-preset-proposal-typescript/commit/3f18e811bc81941b9d8f5285636d44c123fb0afa)) 50 | 51 | ## [1.5.0](https://github.com/un-ts/babel-preset-proposal-typescript/compare/v1.4.6...v1.5.0) (2019-11-10) 52 | 53 | ### Features 54 | 55 | - drop nullish-coalescing-operator and optional-chaining in favor of typescript 3.7.0 ([0fe0093](https://github.com/un-ts/babel-preset-proposal-typescript/commit/0fe0093e22c60c8a04846e643c8998ff5c28fc29)) 56 | 57 | ### [1.4.6](https://github.com/un-ts/babel-preset-proposal-typescript/compare/v1.4.5...v1.4.6) (2019-11-10) 58 | 59 | ### Features 60 | 61 | - better TypeScript support ([66f65c5](https://github.com/un-ts/babel-preset-proposal-typescript/commit/66f65c51bec7d4c67eb1d3f65438a831b2dfe67d)) 62 | 63 | ### Bug Fixes 64 | 65 | - lock rollup-plugin-url@^2.2.4 for node 8 ([d0b7bae](https://github.com/un-ts/babel-preset-proposal-typescript/commit/d0b7baead76b14384326ad72acf1ee1e51409940)) 66 | 67 | ### [1.4.5](https://github.com/un-ts/babel-preset-proposal-typescript/compare/v1.4.4...v1.4.5) (2019-10-09) 68 | 69 | ### [1.4.4](https://github.com/un-ts/babel-preset-proposal-typescript/compare/v1.4.3...v1.4.4) (2019-10-09) 70 | 71 | ### Bug Fixes 72 | 73 | - check typeof decoratorsBeforeExport ([336dc46](https://github.com/un-ts/babel-preset-proposal-typescript/commit/336dc4613f188b7a3250ab33acc3bbbddf82f996)) 74 | 75 | ### [1.4.3](https://github.com/un-ts/babel-preset-proposal-typescript/compare/v1.4.2...v1.4.3) (2019-10-09) 76 | 77 | ### Bug Fixes 78 | 79 | - add decoratorsBeforeExport options for decorators ([1b84269](https://github.com/un-ts/babel-preset-proposal-typescript/commit/1b84269d54bbf72b10322d2c07155ea8b128a546)) 80 | 81 | ### [1.4.2](https://github.com/un-ts/babel-preset-proposal-typescript/compare/v1.4.1...v1.4.2) (2019-10-09) 82 | 83 | ### Bug Fixes 84 | 85 | - compatible with decorators + class properties ([11f7ec4](https://github.com/un-ts/babel-preset-proposal-typescript/commit/11f7ec4cf72e7ba63705cc0d3b297b04ff1a28ec)) 86 | 87 | ### [1.4.1](https://github.com/un-ts/babel-preset-proposal-typescript/compare/v1.4.0...v1.4.1) (2019-09-09) 88 | 89 | ### Bug Fixes 90 | 91 | - **test:** code coverage issue, remove unnecessary tempy dep ([71b6765](https://github.com/un-ts/babel-preset-proposal-typescript/commit/71b6765)) 92 | 93 | ## [1.4.0](https://github.com/un-ts/babel-preset-proposal-typescript/compare/v1.3.0...v1.4.0) (2019-09-07) 94 | 95 | ### Bug Fixes 96 | 97 | - **deps:** bump babel which supports private static accessors ([eb1880d](https://github.com/un-ts/babel-preset-proposal-typescript/commit/eb1880d)) 98 | 99 | ### Features 100 | 101 | - enable v8intrinsic plugin ([7f83401](https://github.com/un-ts/babel-preset-proposal-typescript/commit/7f83401)) 102 | 103 | ## [1.3.0](https://github.com/un-ts/babel-preset-proposal-typescript/compare/v1.2.6...v1.3.0) (2019-09-03) 104 | 105 | ### Features 106 | 107 | - add cjs/esm/es2015 bundle via @1stg/rollup-config ([93e4786](https://github.com/un-ts/babel-preset-proposal-typescript/commit/93e4786)) 108 | 109 | ### [1.2.6](https://github.com/JounQin/babel-preset-proposal-typescript/compare/v1.2.5...v1.2.6) (2019-08-20) 110 | 111 | ### Bug Fixes 112 | 113 | - incorrect type of overrides ([d86062a](https://github.com/JounQin/babel-preset-proposal-typescript/commit/d86062a)) 114 | 115 | ### [1.2.5](https://github.com/JounQin/babel-preset-proposal-typescript/compare/v1.2.4...v1.2.5) (2019-08-20) 116 | 117 | ### Features 118 | 119 | - add back option `isTSX` ([978fa86](https://github.com/JounQin/babel-preset-proposal-typescript/commit/978fa86)) 120 | 121 | ### [1.2.4](https://github.com/JounQin/babel-preset-proposal-typescript/compare/v1.2.3...v1.2.4) (2019-08-18) 122 | 123 | ### [1.2.3](https://github.com/JounQin/babel-preset-proposal-typescript/compare/v1.2.2...v1.2.3) (2019-08-18) 124 | 125 | ### Bug Fixes 126 | 127 | - determine jsx/tsx automatically ([56a08a2](https://github.com/JounQin/babel-preset-proposal-typescript/commit/56a08a2)) 128 | 129 | ### [1.2.2](https://github.com/JounQin/babel-preset-proposal-typescript/compare/v1.2.1...v1.2.2) (2019-08-18) 130 | 131 | ### Features 132 | 133 | - add options support, import documentation ([e2c2064](https://github.com/JounQin/babel-preset-proposal-typescript/commit/e2c2064)) 134 | 135 | ### [1.2.1](https://github.com/JounQin/babel-preset-proposal-typescript/compare/v1.2.0...v1.2.1) (2019-08-18) 136 | 137 | ### Bug Fixes 138 | 139 | - babel plugins should be dependencies ([1ca379c](https://github.com/JounQin/babel-preset-proposal-typescript/commit/1ca379c)) 140 | 141 | ## [1.2.0](https://github.com/JounQin/babel-preset-proposal-typescript/compare/v1.1.0...v1.2.0) (2019-08-17) 142 | 143 | ### Features 144 | 145 | - add latested proposal plugins ([a7f09da](https://github.com/JounQin/babel-preset-proposal-typescript/commit/a7f09da)) 146 | 147 | ## 1.1.0 (2019-08-17) 148 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017 JounQin 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. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # babel-preset-proposal-typescript 2 | 3 | [![GitHub Actions](https://github.com/un-ts/babel-preset-proposal-typescript/workflows/CI/badge.svg)](https://github.com/un-ts/babel-preset-proposal-typescript/actions/workflows/ci.yml) 4 | [![Codecov](https://img.shields.io/codecov/c/github/un-ts/babel-preset-proposal-typescript.svg)](https://codecov.io/gh/un-ts/babel-preset-proposal-typescript) 5 | [![npm](https://img.shields.io/npm/v/babel-preset-proposal-typescript.svg)](https://www.npmjs.com/package/babel-preset-proposal-typescript) 6 | [![GitHub Release](https://img.shields.io/github/release/un-ts/babel-preset-proposal-typescript)](https://github.com/un-ts/babel-preset-proposal-typescript/releases) 7 | 8 | [![Conventional Commits](https://img.shields.io/badge/conventional%20commits-1.0.0-yellow.svg)](https://conventionalcommits.org) 9 | [![Renovate enabled](https://img.shields.io/badge/renovate-enabled-brightgreen.svg)](https://renovatebot.com) 10 | [![JavaScript Style Guide](https://img.shields.io/badge/code_style-standard-brightgreen.svg)](https://standardjs.com) 11 | [![Code Style: Prettier](https://img.shields.io/badge/code_style-prettier-ff69b4.svg)](https://github.com/prettier/prettier) 12 | [![changesets](https://img.shields.io/badge/maintained%20with-changesets-176de3.svg)](https://github.com/atlassian/changesets) 13 | 14 | Yet another Babel preset for TypeScript, only transforms proposals which TypeScript does not support now. 15 | 16 | So that you can use babel to transform proposals which are current in stage 0-2 and TypeScript team [will not implement them temporarily](https://github.com/Microsoft/TypeScript/issues/19044#event-1293164503). 17 | 18 | ## TOC 19 | 20 | - [Enabled proposal plugins](#enabled-proposal-plugins) 21 | - [Install](#install) 22 | - [Options](#options) 23 | - [Usage](#usage) 24 | - [Via `.babelrc` (Recommended)](#via-babelrc-recommended) 25 | - [Via CLI](#via-cli) 26 | - [Via Node API](#via-node-api) 27 | - [Via webpack](#via-webpack) 28 | - [References](#references) 29 | - [Sponsors](#sponsors) 30 | - [Backers](#backers) 31 | - [Changelog](#changelog) 32 | - [License](#license) 33 | 34 | ## Enabled proposal plugins 35 | 36 | 1. [async-do-expressions](https://www.npmjs.com/package/@babel/plugin-proposal-async-do-expressions) 37 | 2. [destructuring-private](https://www.npmjs.com/package/@babel/plugin-proposal-destructuring-private) 38 | 3. [do-expressions](https://www.npmjs.com/package/@babel/plugin-proposal-do-expressions) 39 | 4. [duplicate-named-capturing-groups-regex](https://www.npmjs.com/package/@babel/plugin-proposal-duplicate-named-capturing-groups-regex) 40 | 5. [function-bind](https://www.npmjs.com/package/@babel/plugin-proposal-function-bind) 41 | 6. [function-sent](https://www.npmjs.com/package/@babel/plugin-proposal-function-sent) 42 | 7. [import-defer](https://www.npmjs.com/package/@babel/plugin-proposal-import-defer) 43 | 8. [import-wasm-source](https://www.npmjs.com/package/@babel/plugin-proposal-import-wasm-source) 44 | 9. [optional-chaining-assign](https://www.npmjs.com/package/@babel/plugin-proposal-optional-chaining-assign) 45 | 10. [partial-application](https://www.npmjs.com/package/@babel/plugin-proposal-partial-application) 46 | 11. [pipeline-operator](https://www.npmjs.com/package/@babel/plugin-proposal-pipeline-operator) 47 | 12. [record-and-tuple](https://www.npmjs.com/package/@babel/plugin-proposal-record-and-tuple) 48 | 13. [regexp-modifiers](https://www.npmjs.com/package/@babel/plugin-proposal-regexp-modifiers) 49 | 14. [throw-expressions](https://www.npmjs.com/package/@babel/plugin-proposal-throw-expressions) 50 | 15. [v8intrinsic](./src/v8intrinsic.ts) - [Further Detail](https://babeljs.io/blog/2019/09/05/7.6.0#v8-intrinsic-runtime-functions-parsing-10148httpsgithubcombabelbabelpull10148) 51 | 52 | ## Install 53 | 54 | ```sh 55 | # yarn 56 | yarn add -D babel-preset-proposal-typescript 57 | 58 | # npm 59 | npm i -D babel-preset-proposal-typescript 60 | ``` 61 | 62 | ## Options 63 | 64 | | option | description | defaults | 65 | | ------------------------------- | ------------------------------------------------------------------------------------------------------------ | ----------------------------------------------------------------------- | 66 | | `decoratorsBeforeExport` | See [Babel Document](https://babeljs.io/docs/en/babel-plugin-proposal-decorators#decoratorsbeforeexport) | `undefined` | 67 | | `decoratorsLegacy` | Whether to use legacy decorators semantic | `true` | 68 | | `importDefer` | Whether to enabled `import-defer` plugin, if true `transform-modules-commonjs` will be enabled automatically | `false` | 69 | | `isTSX` | Whether to enable `jsx` plugin with `typescript` | `false`, but `true` for `/\.[jt]sx$/` | 70 | | `optionalChainingAssignVersion` | Version for `optional-chaining-assign` plugin, only `'2023-07'` allowed for now | `'2023-07'` | 71 | | `pipelineOperator` | Implementation of pipeline operator, `minimal`, `smart` or `fsharp` | `minimal` | 72 | | `recordTuplePolyfill` | Whether to enable import `record-tuple` plugin and polyfill, or specific the polyfill module name | `true` for Node>=14.6, it represents `@bloomberg/record-tuple-polyfill` | 73 | | `recordTupleSyntaxType` | `record-tuple` syntax, `hash` or `bar` | `hash` | 74 | 75 | ## Usage 76 | 77 | Note that unlike plugins, the presets are applied in an order of last to first (), so please make sure `proposal-typescript` is used at the last. 78 | 79 | ### Via `.babelrc` (Recommended) 80 | 81 | **.babelrc** 82 | 83 | ```json 84 | { 85 | "presets": ["proposal-typescript"] 86 | } 87 | ``` 88 | 89 | ### Via CLI 90 | 91 | ```sh 92 | babel input.ts --presets proposal-typescript > output.ts 93 | ``` 94 | 95 | ### Via Node API 96 | 97 | ```js 98 | require('@babel/core').transform('code', { 99 | presets: ['proposal-typescript'], 100 | }) 101 | ``` 102 | 103 | ### Via webpack 104 | 105 | Pipe codes through `babel-loader`. 106 | 107 | ```js 108 | loader = { 109 | test: /\.[jt]sx?$/, 110 | loader: 'babel-loader', 111 | options: { 112 | presets: ['@babel/typescript', 'proposal-typescript'], 113 | }, 114 | } 115 | 116 | // if you prefer `ts-loader` or `awesome-typescript-loader` 117 | loader = { 118 | test: /\.tsx?$/, 119 | use: [ 120 | { 121 | loader: 'ts-loader', 122 | }, 123 | { 124 | loader: 'babel-loader', 125 | options: { 126 | presets: ['proposal-typescript'], 127 | }, 128 | }, 129 | ], 130 | } 131 | ``` 132 | 133 | ## References 134 | 135 | - [TC39 Proposals](https://github.com/tc39/proposals) 136 | - [Babel Proposals](https://github.com/babel/proposals) 137 | 138 | ## Sponsors 139 | 140 | | 1stG | RxTS | UnTS | 141 | | ---------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------- | 142 | | [![1stG Open Collective backers and sponsors](https://opencollective.com/1stG/organizations.svg)](https://opencollective.com/1stG) | [![RxTS Open Collective backers and sponsors](https://opencollective.com/rxts/organizations.svg)](https://opencollective.com/rxts) | [![UnTS Open Collective backers and sponsors](https://opencollective.com/unts/organizations.svg)](https://opencollective.com/unts) | 143 | 144 | ## Backers 145 | 146 | [![Backers](https://raw.githubusercontent.com/1stG/static/master/sponsors.svg)](https://github.com/sponsors/JounQin) 147 | 148 | | 1stG | RxTS | UnTS | 149 | | -------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------- | 150 | | [![1stG Open Collective backers and sponsors](https://opencollective.com/1stG/individuals.svg)](https://opencollective.com/1stG) | [![RxTS Open Collective backers and sponsors](https://opencollective.com/rxts/individuals.svg)](https://opencollective.com/rxts) | [![UnTS Open Collective backers and sponsors](https://opencollective.com/unts/individuals.svg)](https://opencollective.com/unts) | 151 | 152 | ## Changelog 153 | 154 | Detailed changes for each release are documented in [CHANGELOG.md](./CHANGELOG.md). 155 | 156 | ## License 157 | 158 | [MIT][] © [JounQin][]@[1stG.me][] 159 | 160 | [1stg.me]: https://www.1stg.me 161 | [jounqin]: https://GitHub.com/JounQin 162 | [mit]: http://opensource.org/licenses/MIT 163 | -------------------------------------------------------------------------------- /babel.config.cjs: -------------------------------------------------------------------------------- 1 | const isRecordTupleSupported = require('./scripts/is-record-tuple-supported.cjs') 2 | 3 | module.exports = { 4 | sourceType: 'module', 5 | presets: [ 6 | [ 7 | '@babel/env', 8 | { 9 | targets: { 10 | node: true, 11 | }, 12 | }, 13 | ], 14 | [ 15 | '@babel/typescript', 16 | { 17 | allowDeclareFields: true, 18 | }, 19 | ], 20 | 'proposal-typescript', 21 | ], 22 | plugins: isRecordTupleSupported() 23 | ? undefined 24 | : [ 25 | [ 26 | '@babel/syntax-record-and-tuple', 27 | { 28 | syntaxType: 'hash', 29 | }, 30 | ], 31 | ], 32 | overrides: [ 33 | { 34 | test: 'test/import-defer.cts', 35 | presets: [ 36 | [ 37 | 'proposal-typescript', 38 | { 39 | importDefer: true, 40 | }, 41 | ], 42 | ], 43 | }, 44 | ], 45 | } 46 | -------------------------------------------------------------------------------- /jest.config.js: -------------------------------------------------------------------------------- 1 | // @ts-check 2 | 3 | import isRecordTupleSupported from './scripts/is-record-tuple-supported.cjs' 4 | 5 | /** 6 | * @type {import('jest').Config} 7 | */ 8 | export default { 9 | extensionsToTreatAsEsm: ['.ts'], 10 | moduleNameMapper: { 11 | '^(\\.{1,2}/.*)\\.js$': '$1', 12 | '^(\\.{1,2}/.*)\\.cjs$': ['$1.cts', '$1.cjs'], 13 | }, 14 | transform: { 15 | '^.+\\.([c|m]?[j|t])s$': 'babel-jest', 16 | }, 17 | collectCoverage: true, 18 | collectCoverageFrom: [ 19 | `/test/**/!(${ 20 | isRecordTupleSupported() ? '' : 'record-and-tuple|' 21 | }v8intrinsic).ts`, 22 | ], 23 | coverageThreshold: { 24 | global: { 25 | branches: 100, 26 | functions: 100, 27 | lines: 100, 28 | statements: 100, 29 | }, 30 | }, 31 | } 32 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "babel-preset-proposal-typescript", 3 | "version": "4.0.0", 4 | "type": "module", 5 | "description": "Yet another Babel preset for TypeScript, only transforms proposals which TypeScript does not support now.", 6 | "repository": "git+https://github.com/un-ts/babel-preset-proposal-typescript.git", 7 | "author": "JounQin ", 8 | "license": "MIT", 9 | "packageManager": "yarn@1.22.21", 10 | "engines": { 11 | "node": ">=6.9.0" 12 | }, 13 | "main": "lib/index.cjs", 14 | "module": "lib/index.js", 15 | "exports": { 16 | "types": "./lib/index.d.ts", 17 | "es2015": "./lib/index.es2015.mjs", 18 | "fesm2015": "./lib/index.es2015.mjs", 19 | "import": "./lib/index.js", 20 | "require": "./lib/index.cjs" 21 | }, 22 | "es2015": "lib/index.es2015.mjs", 23 | "fesm2015": "lib/index.es2015.mjs", 24 | "types": "lib", 25 | "files": [ 26 | "lib", 27 | "!*.tsbuildinfo" 28 | ], 29 | "keywords": [ 30 | "babel-preset", 31 | "babel-preset-ts", 32 | "babel-preset-typescript", 33 | "@babel/preset-ts", 34 | "@babel/preset-typescript", 35 | "babel-typescript", 36 | "typescript" 37 | ], 38 | "scripts": { 39 | "build": "run-p build:*", 40 | "build:r": "r -f cjs,es2015", 41 | "build:ts": "tsc -p src", 42 | "lint": "run-p lint:*", 43 | "lint:es": "eslint . --cache -f friendly", 44 | "lint:tsc": "tsc -p src --noEmit", 45 | "prepack": "clean-pkg-json", 46 | "prepare": "simple-git-hooks && yarn-deduplicate --strategy fewer || exit 0", 47 | "prerelease": "yarn build", 48 | "pretest": "yarn build", 49 | "release": "changeset publish", 50 | "test": "node --experimental-vm-modules node_modules/jest/bin/jest" 51 | }, 52 | "peerDependencies": { 53 | "@babel/core": "^7.23.0", 54 | "typescript": "^5.3.0" 55 | }, 56 | "dependencies": { 57 | "@babel/helper-plugin-utils": "^7.22.5", 58 | "@babel/plugin-proposal-async-do-expressions": "^7.23.3", 59 | "@babel/plugin-proposal-destructuring-private": "^7.23.3", 60 | "@babel/plugin-proposal-do-expressions": "^7.23.3", 61 | "@babel/plugin-proposal-duplicate-named-capturing-groups-regex": "^7.23.3", 62 | "@babel/plugin-proposal-function-bind": "^7.23.3", 63 | "@babel/plugin-proposal-function-sent": "^7.23.3", 64 | "@babel/plugin-proposal-import-defer": "^7.23.0", 65 | "@babel/plugin-proposal-import-wasm-source": "^7.23.0", 66 | "@babel/plugin-proposal-optional-chaining-assign": "^7.23.0", 67 | "@babel/plugin-proposal-partial-application": "^7.23.3", 68 | "@babel/plugin-proposal-pipeline-operator": "^7.23.3", 69 | "@babel/plugin-proposal-private-property-in-object": "^7.21.11", 70 | "@babel/plugin-proposal-record-and-tuple": "^7.23.3", 71 | "@babel/plugin-proposal-regexp-modifiers": "^7.23.3", 72 | "@babel/plugin-proposal-throw-expressions": "^7.23.3", 73 | "@babel/plugin-syntax-decorators": "^7.23.3", 74 | "@babel/plugin-syntax-typescript": "^7.23.3", 75 | "@babel/plugin-transform-modules-commonjs": "^7.23.3", 76 | "@bloomberg/record-tuple-polyfill": "^0.0.4" 77 | }, 78 | "devDependencies": { 79 | "@1stg/lib-config": "^12.0.1", 80 | "@babel/core": "^7.23.6", 81 | "@changesets/changelog-github": "^0.5.0", 82 | "@changesets/cli": "^2.27.1", 83 | "@node-loader/babel": "^2.0.1", 84 | "@types/babel__core": "^7.20.5", 85 | "@types/jest": "^29.5.11", 86 | "@types/node": "^18.19.3", 87 | "@vitest/coverage-istanbul": "^1.0.4", 88 | "clean-pkg-json": "^1.2.0", 89 | "core-dts": "^0.0.3", 90 | "jest": "^29.7.0", 91 | "ts-node": "^10.9.2", 92 | "typescript": "^5.3.3", 93 | "yarn-deduplicate": "^6.0.2" 94 | }, 95 | "resolutions": { 96 | "babel-preset-proposal-typescript": "link:.", 97 | "prettier": "^2.8.8" 98 | } 99 | } 100 | -------------------------------------------------------------------------------- /scripts/is-record-tuple-supported.cjs: -------------------------------------------------------------------------------- 1 | const [major, minor] = process.versions.node.split('.') 2 | 3 | // eslint-disable-next-line no-magic-numbers 4 | module.exports = () => +major > 14 || (+major === 14 && +minor >= 6) 5 | -------------------------------------------------------------------------------- /src/index.ts: -------------------------------------------------------------------------------- 1 | import type { ConfigAPI } from '@babel/core' 2 | import { declare } from '@babel/helper-plugin-utils' 3 | import proposalAsyncDoExpressions from '@babel/plugin-proposal-async-do-expressions' 4 | import proposalDestructuringPrivate from '@babel/plugin-proposal-destructuring-private' 5 | import proposalDoExpressions from '@babel/plugin-proposal-do-expressions' 6 | import proposalDuplicateNamedCapturingGroupsRegex from '@babel/plugin-proposal-duplicate-named-capturing-groups-regex' 7 | import proposalFunctionBind from '@babel/plugin-proposal-function-bind' 8 | import proposalFunctionSent from '@babel/plugin-proposal-function-sent' 9 | import proposalImportDefer from '@babel/plugin-proposal-import-defer' 10 | import proposalImportWasmSource from '@babel/plugin-proposal-import-wasm-source' 11 | import proposalOptionalChainingAssign from '@babel/plugin-proposal-optional-chaining-assign' 12 | import proposalPartialApplication from '@babel/plugin-proposal-partial-application' 13 | import proposalPipelineOperator from '@babel/plugin-proposal-pipeline-operator' 14 | import proposalRecordAndTuple from '@babel/plugin-proposal-record-and-tuple' 15 | import proposalRegexpModifiers from '@babel/plugin-proposal-regexp-modifiers' 16 | import proposalThrowExpression from '@babel/plugin-proposal-throw-expressions' 17 | import syntaxDecorators from '@babel/plugin-syntax-decorators' 18 | import syntaxTypeScript from '@babel/plugin-syntax-typescript' 19 | import transformModulesCommonjs from '@babel/plugin-transform-modules-commonjs' 20 | 21 | import { IS_RECORD_TUPLE_SUPPORTED } from './utils.js' 22 | import syntaxV8intrinsic from './v8intrinsic.js' 23 | 24 | export interface ProposalTypeScriptOptions { 25 | decoratorsBeforeExport?: boolean 26 | decoratorsLegacy?: boolean 27 | importDefer?: boolean | 'commonjs' 28 | isTSX?: boolean 29 | optionalChainingAssignVersion?: '2023-07' 30 | pipelineOperator?: 'fsharp' | 'minimal' | 'smart' 31 | recordTuplePolyfill?: boolean | string 32 | recordTupleSyntaxType?: 'bar' | 'hash' 33 | } 34 | 35 | export default declare( 36 | ( 37 | api: ConfigAPI, 38 | { 39 | decoratorsBeforeExport, 40 | decoratorsLegacy = true, 41 | importDefer, 42 | isTSX, 43 | pipelineOperator = 'minimal', 44 | optionalChainingAssignVersion = '2023-07', 45 | recordTuplePolyfill = IS_RECORD_TUPLE_SUPPORTED, 46 | recordTupleSyntaxType = 'hash', 47 | }: ProposalTypeScriptOptions, 48 | ) => { 49 | api.assertVersion(7) 50 | return { 51 | plugins: [ 52 | [ 53 | syntaxDecorators, 54 | { 55 | decoratorsBeforeExport, 56 | legacy: decoratorsLegacy, 57 | }, 58 | ], 59 | [ 60 | syntaxTypeScript, 61 | { 62 | isTSX, 63 | }, 64 | ], 65 | syntaxV8intrinsic, 66 | proposalAsyncDoExpressions, 67 | proposalDestructuringPrivate, 68 | proposalDuplicateNamedCapturingGroupsRegex, 69 | proposalDoExpressions, 70 | proposalFunctionBind, 71 | proposalFunctionSent, 72 | ...(importDefer ? [proposalImportDefer, transformModulesCommonjs] : []), 73 | proposalPartialApplication, 74 | proposalImportWasmSource, 75 | [ 76 | proposalOptionalChainingAssign, 77 | { 78 | version: optionalChainingAssignVersion, 79 | }, 80 | ], 81 | [ 82 | proposalPipelineOperator, 83 | { 84 | proposal: pipelineOperator, 85 | }, 86 | ], 87 | recordTuplePolyfill && [ 88 | proposalRecordAndTuple, 89 | { 90 | importPolyfill: !!recordTuplePolyfill, 91 | polyfillModuleName: 92 | typeof recordTuplePolyfill === 'string' 93 | ? recordTuplePolyfill 94 | : undefined, 95 | syntaxType: recordTupleSyntaxType, 96 | }, 97 | ], 98 | proposalRegexpModifiers, 99 | proposalThrowExpression, 100 | ].filter(Boolean), 101 | // no need to override if it has been enabled 102 | overrides: isTSX 103 | ? undefined 104 | : [ 105 | { 106 | test: /\.[jt]sx$/, 107 | plugins: [ 108 | [ 109 | syntaxTypeScript, 110 | { 111 | isTSX: true, 112 | }, 113 | ], 114 | ], 115 | }, 116 | ], 117 | } 118 | }, 119 | ) 120 | -------------------------------------------------------------------------------- /src/shim.d.ts: -------------------------------------------------------------------------------- 1 | declare module '@babel/helper-plugin-utils' { 2 | import { ConfigAPI, PluginItem } from '@babel/core' 3 | 4 | export const declare: ( 5 | fn: (api: ConfigAPI, options: object) => PluginItem, 6 | ) => PluginItem 7 | } 8 | 9 | declare module '@babel/*' 10 | -------------------------------------------------------------------------------- /src/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "..", 3 | "compilerOptions": { 4 | "rootDir": ".", 5 | "outDir": "../lib" 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /src/utils.ts: -------------------------------------------------------------------------------- 1 | const [major, minor] = process.versions.node.split('.') 2 | 3 | export const IS_RECORD_TUPLE_SUPPORTED = 4 | // eslint-disable-next-line no-magic-numbers 5 | +major > 14 || (+major === 14 && +minor >= 6) 6 | -------------------------------------------------------------------------------- /src/v8intrinsic.ts: -------------------------------------------------------------------------------- 1 | import { ConfigAPI, TransformOptions } from '@babel/core' 2 | import { declare } from '@babel/helper-plugin-utils' 3 | 4 | export default declare((api: ConfigAPI) => { 5 | api.assertVersion(7) 6 | return { 7 | name: 'v8intrinsic', 8 | manipulateOptions(_opts: unknown, parserOpts: TransformOptions) { 9 | parserOpts.plugins!.push('v8intrinsic') 10 | }, 11 | } 12 | }) 13 | -------------------------------------------------------------------------------- /test/__snapshots__/destructuring-private.spec.ts.snap: -------------------------------------------------------------------------------- 1 | // Jest Snapshot v1, https://goo.gl/fbAQLP 2 | 3 | exports[`destructuring-private: "Unexpected token ';'" 1`] = `"Unexpected token ';'"`; 4 | -------------------------------------------------------------------------------- /test/__snapshots__/do-expressions.spec.ts.snap: -------------------------------------------------------------------------------- 1 | // Jest Snapshot v1, https://goo.gl/fbAQLP 2 | 3 | exports[`do-expressions 1`] = `"Unexpected token ')'"`; 4 | -------------------------------------------------------------------------------- /test/__snapshots__/duplicate-named-capturing-groups-regex.spec.ts.snap: -------------------------------------------------------------------------------- 1 | // Jest Snapshot v1, https://goo.gl/fbAQLP 2 | 3 | exports[`duplicate-named-capturing-groups-regex 1`] = `"Invalid regular expression: /(?\\d{4})-(?\\d{2})|(?\\d{2})-(?\\d{4})/: Duplicate capture group name"`; 4 | -------------------------------------------------------------------------------- /test/__snapshots__/import-defer.spec.ts.snap: -------------------------------------------------------------------------------- 1 | // Jest Snapshot v1, https://goo.gl/fbAQLP 2 | 3 | exports[`import-defer 1`] = `"Unexpected token '*'"`; 4 | -------------------------------------------------------------------------------- /test/__snapshots__/import-wasm-source.spec.ts.snap: -------------------------------------------------------------------------------- 1 | // Jest Snapshot v1, https://goo.gl/fbAQLP 2 | 3 | exports[`import-wasm-source 1`] = `"from is not defined"`; 4 | -------------------------------------------------------------------------------- /test/__snapshots__/partial-application.spec.ts.snap: -------------------------------------------------------------------------------- 1 | // Jest Snapshot v1, https://goo.gl/fbAQLP 2 | 3 | exports[`partial-application 1`] = `"addOne is not a function"`; 4 | -------------------------------------------------------------------------------- /test/__snapshots__/pipeline-operator.spec.ts.snap: -------------------------------------------------------------------------------- 1 | // Jest Snapshot v1, https://goo.gl/fbAQLP 2 | 3 | exports[`pipeline-operator 1`] = `"Unexpected token '>'"`; 4 | -------------------------------------------------------------------------------- /test/__snapshots__/record-and-tuple.spec.ts.snap: -------------------------------------------------------------------------------- 1 | // Jest Snapshot v1, https://goo.gl/fbAQLP 2 | 3 | exports[`record-and-tuple 1`] = `"Unexpected token ','"`; 4 | -------------------------------------------------------------------------------- /test/__snapshots__/regexp-modifiers.spec.ts.snap: -------------------------------------------------------------------------------- 1 | // Jest Snapshot v1, https://goo.gl/fbAQLP 2 | 3 | exports[`regexp-modifiers 1`] = `"Invalid regular expression: /(?i:a)a/: Invalid group"`; 4 | -------------------------------------------------------------------------------- /test/__snapshots__/throw-expressions.spec.ts.snap: -------------------------------------------------------------------------------- 1 | // Jest Snapshot v1, https://goo.gl/fbAQLP 2 | 3 | exports[`throw-expressions 1`] = `"Unexpected token ')'"`; 4 | -------------------------------------------------------------------------------- /test/__snapshots__/v8intrinsic.spec.ts.snap: -------------------------------------------------------------------------------- 1 | // Jest Snapshot v1, https://goo.gl/fbAQLP 2 | 3 | exports[`v8intrinsic 1`] = `"Unexpected token '%'"`; 4 | 5 | exports[`v8intrinsic 2`] = `"Unexpected token '%'"`; 6 | -------------------------------------------------------------------------------- /test/async-do-expressions.spec.ts: -------------------------------------------------------------------------------- 1 | import _ from './async-do-expressions.js' 2 | import { execute } from './helpers.js' 3 | 4 | const proposal = 'async-do-expressions' 5 | 6 | test(proposal, async () => { 7 | expect(() => execute(proposal)).toThrow( 8 | 'await is only valid in async function', 9 | ) 10 | expect(await _).toEqual([2, 6]) 11 | }) 12 | -------------------------------------------------------------------------------- /test/async-do-expressions.ts: -------------------------------------------------------------------------------- 1 | export default Promise.all([ 2 | async do { 3 | const result = await Promise.resolve(1) 4 | result * 2 5 | }, 6 | async do { 7 | const result = await Promise.resolve(2) 8 | result * 3 9 | }, 10 | ]) 11 | -------------------------------------------------------------------------------- /test/declare-field.spec.ts: -------------------------------------------------------------------------------- 1 | import Test from './declare-field.js' 2 | 3 | const testCase = 'declare-field' 4 | 5 | test(testCase, async () => { 6 | expect(new Test(2).a).toEqual(1) 7 | }) 8 | -------------------------------------------------------------------------------- /test/declare-field.ts: -------------------------------------------------------------------------------- 1 | export default class Test { 2 | declare a: number 3 | 4 | constructor(a: number) { 5 | this.a = a / 2 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /test/destructuring-private.spec.ts: -------------------------------------------------------------------------------- 1 | import _ from './destructuring-private.js' 2 | import { execute } from './helpers.js' 3 | 4 | const proposal = 'destructuring-private' 5 | 6 | test(proposal, () => { 7 | expect(() => execute(proposal)).toThrowErrorMatchingSnapshot( 8 | `"Unexpected token ';'"`, 9 | ) 10 | expect(_(1, 0)).toEqual(true) 11 | expect(_(0, 1)).toEqual(false) 12 | }) 13 | -------------------------------------------------------------------------------- /test/destructuring-private.ts: -------------------------------------------------------------------------------- 1 | class Point { 2 | x: number 3 | #y = 0 4 | 5 | constructor(x: number, y: number) { 6 | this.x = x 7 | this.#y = y 8 | } 9 | 10 | equalsTo({ x, #y: y }: this) { 11 | return this.x === x && this.#y === y 12 | } 13 | } 14 | 15 | export default (x: number, y: number) => 16 | new Point(x, y).equalsTo(new Point(1, 0)) 17 | -------------------------------------------------------------------------------- /test/do-expressions.spec.ts: -------------------------------------------------------------------------------- 1 | import _ from './do-expressions.js' 2 | import { execute } from './helpers.js' 3 | 4 | const proposal = 'do-expressions' 5 | 6 | test(proposal, () => { 7 | expect(() => execute(proposal)).toThrowErrorMatchingSnapshot() 8 | expect(_(20)).toBe('big') 9 | expect(_(0)).toBe('small') 10 | }) 11 | -------------------------------------------------------------------------------- /test/do-expressions.ts: -------------------------------------------------------------------------------- 1 | const BIG = 'big' 2 | const SMALL = 'small' 3 | 4 | export default (num: number): typeof BIG | typeof SMALL => do { 5 | if (num > 10) { 6 | BIG 7 | } else { 8 | SMALL 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /test/duplicate-named-capturing-groups-regex.spec.ts: -------------------------------------------------------------------------------- 1 | import _ from './duplicate-named-capturing-groups-regex.js' 2 | import { execute } from './helpers.js' 3 | 4 | const proposal = 'duplicate-named-capturing-groups-regex' 5 | 6 | test(proposal, () => { 7 | expect(() => execute(proposal)).toThrowErrorMatchingSnapshot() 8 | expect(_('02-1999')).toMatchInlineSnapshot(`"1999"`) 9 | }) 10 | -------------------------------------------------------------------------------- /test/duplicate-named-capturing-groups-regex.ts: -------------------------------------------------------------------------------- 1 | const re = /(?\d{4})-(?\d{2})|(?\d{2})-(?\d{4})/ 2 | 3 | export default (input: string) => re.exec(input)!.groups!.year 4 | -------------------------------------------------------------------------------- /test/function-bind.spec.ts: -------------------------------------------------------------------------------- 1 | import _ from './function-bind.js' 2 | import { execute } from './helpers.js' 3 | 4 | const proposal = 'function-bind' 5 | 6 | test(proposal, () => { 7 | // Cannot read property 'weight' of undefined 8 | // vs. 9 | // Cannot read properties of undefined (reading 'weight') 10 | expect(() => execute(proposal)).toThrow(/^Cannot read propert(y|ies) /) 11 | expect(_()).toEqual([2, 10, 15]) 12 | }) 13 | -------------------------------------------------------------------------------- /test/function-bind.ts: -------------------------------------------------------------------------------- 1 | const box = { 2 | weight: 2, 3 | getWeight(): number { 4 | return this.weight 5 | }, 6 | } 7 | 8 | const bigBox = { weight: 10 } 9 | 10 | // Can be chained: 11 | function add(this: number, val: number) { 12 | // eslint-disable-next-line @babel/no-invalid-this 13 | return this + val 14 | } 15 | 16 | export default () => { 17 | const result = [] 18 | 19 | result.push(box.getWeight()) 20 | 21 | const { getWeight } = box 22 | result.push(bigBox::getWeight(), bigBox::getWeight()::add(5)) 23 | 24 | return result 25 | } 26 | -------------------------------------------------------------------------------- /test/function-sent.spec.ts: -------------------------------------------------------------------------------- 1 | import _ from './function-sent.js' 2 | import { execute } from './helpers.js' 3 | 4 | const proposal = 'function-sent' 5 | 6 | test(proposal, () => { 7 | const args = [0.3, 0.4, 0.5] 8 | const expectResult = 2.2 9 | expect(execute(proposal, ...args)).not.toEqual(expectResult) 10 | expect(_(...args)).toBe(expectResult) 11 | }) 12 | -------------------------------------------------------------------------------- /test/function-sent.ts: -------------------------------------------------------------------------------- 1 | function* adder(total = 0) { 2 | let increment = 1 3 | let request 4 | do { 5 | switch ((request = function.sent)) { 6 | case undefined: { 7 | break 8 | } 9 | case 'done': { 10 | return total 11 | } 12 | default: { 13 | increment = request 14 | } 15 | } 16 | yield (total += increment) 17 | } while (true) 18 | } 19 | 20 | export default (...args: number[]) => { 21 | const tally = adder() 22 | tally.next() 23 | for (const arg of args) { 24 | tally.next(arg) 25 | } 26 | return tally.next('done').value 27 | } 28 | -------------------------------------------------------------------------------- /test/helpers.ts: -------------------------------------------------------------------------------- 1 | import fs from 'node:fs' 2 | import path from 'node:path' 3 | import { fileURLToPath } from 'node:url' 4 | import vm from 'node:vm' 5 | 6 | import ts from 'typescript' 7 | 8 | /* istanbul ignore next */ 9 | const _dirname = 10 | typeof __dirname === 'undefined' 11 | ? path.dirname(fileURLToPath(import.meta.url)) 12 | : __dirname 13 | 14 | export const resolve = (...args: string[]): string => 15 | path.resolve(_dirname, ...args) 16 | 17 | export const read = (file: string): string => 18 | fs 19 | .readFileSync(resolve(file) + (/\.[cm]?[jt]s$/.test(file) ? '' : '.ts')) 20 | .toString() 21 | 22 | export const execute = (file: string, ...args: number[] | string[]) => 23 | vm.runInNewContext(ts.transpile(read(file)), { exports: {} })(...args) 24 | -------------------------------------------------------------------------------- /test/import-defer.cts: -------------------------------------------------------------------------------- 1 | import defer * as babel from '@babel/core'; 2 | 3 | export const getVersion = () => babel.version 4 | -------------------------------------------------------------------------------- /test/import-defer.spec.ts: -------------------------------------------------------------------------------- 1 | import { createRequire } from 'node:module' 2 | 3 | import { execute } from './helpers.js' 4 | import * as _ from './import-defer.cjs' 5 | 6 | const cjsRequire = createRequire(import.meta.url) 7 | 8 | const pkg = cjsRequire('@babel/core/package.json') as { 9 | version: string 10 | } 11 | 12 | const proposal = 'import-defer' 13 | 14 | test(proposal, () => { 15 | expect(() => execute(proposal + '.cts')).toThrowErrorMatchingSnapshot() 16 | expect(_.getVersion()).toBe(pkg.version) 17 | }) 18 | -------------------------------------------------------------------------------- /test/import-wasm-source.spec.ts: -------------------------------------------------------------------------------- 1 | import { execute } from './helpers.js' 2 | import _ from './import-wasm-source.js' 3 | 4 | const proposal = 'import-wasm-source' 5 | 6 | test(proposal, () => { 7 | expect(() => execute(proposal)).toThrowErrorMatchingSnapshot() 8 | expect(_()).toBeDefined() 9 | }) 10 | -------------------------------------------------------------------------------- /test/import-wasm-source.ts: -------------------------------------------------------------------------------- 1 | // eslint-disable-next-line prettier/prettier 2 | import source shSyntax from "sh-syntax/main.wasm"; 3 | 4 | export default () => shSyntax; 5 | -------------------------------------------------------------------------------- /test/optional-chaining-assign.spec.ts: -------------------------------------------------------------------------------- 1 | import _ from './optional-chaining-assign.js' 2 | 3 | const proposal = 'optional-chaining-assign' 4 | 5 | test(proposal, () => { 6 | expect(_()).toBe(undefined) 7 | const maybeOptions = { retries: 6 } 8 | const result = _(maybeOptions)! 9 | expect(_(maybeOptions)).toBe(result) 10 | expect(result.retries).toBe(5) 11 | }) 12 | -------------------------------------------------------------------------------- /test/optional-chaining-assign.ts: -------------------------------------------------------------------------------- 1 | export default (maybeOptions?: { retries?: number }) => { 2 | // eslint-disable-next-line prettier/prettier 3 | maybeOptions?.retries = 5; 4 | return maybeOptions 5 | } 6 | -------------------------------------------------------------------------------- /test/partial-application.spec.ts: -------------------------------------------------------------------------------- 1 | import { execute } from './helpers.js' 2 | import _ from './partial-application.js' 3 | 4 | const proposal = 'partial-application' 5 | 6 | test(proposal, () => { 7 | expect(() => execute(proposal)).toThrowErrorMatchingSnapshot() 8 | expect(_()).toEqual([3, 12]) 9 | }) 10 | -------------------------------------------------------------------------------- /test/partial-application.ts: -------------------------------------------------------------------------------- 1 | function add(x: number, y: number) { 2 | return x + y 3 | } 4 | 5 | export default () => { 6 | const addOne = add(1, ?) 7 | const addTen = add(?, 10) 8 | return [addOne(2), addTen(2)] 9 | } 10 | -------------------------------------------------------------------------------- /test/pipeline-operator.spec.ts: -------------------------------------------------------------------------------- 1 | import { execute } from './helpers.js' 2 | import _ from './pipeline-operator.js' 3 | 4 | const proposal = 'pipeline-operator' 5 | 6 | test(proposal, () => { 7 | expect(() => execute(proposal)).toThrowErrorMatchingSnapshot() 8 | expect(_('hello', 25)).toEqual(['Hello, hello!', 57]) 9 | }) 10 | -------------------------------------------------------------------------------- /test/pipeline-operator.ts: -------------------------------------------------------------------------------- 1 | function doubleSay(str: string) { 2 | return str + ', ' + str 3 | } 4 | 5 | function capitalize(str: string) { 6 | return str[0].toUpperCase() + str.slice(1) 7 | } 8 | 9 | function exclaim(str: string) { 10 | return str + '!' 11 | } 12 | 13 | function double(x: number) { 14 | return x + x 15 | } 16 | function add(x: number, y: number) { 17 | return x + y 18 | } 19 | 20 | function boundScore(min: number, max: number, score: number) { 21 | return Math.max(min, Math.min(max, score)) 22 | } 23 | 24 | export default (word: string, score: number) => [ 25 | word |> doubleSay |> capitalize |> exclaim, 26 | 27 | score |> double |> (_ => add(7, _)) |> (_ => boundScore(0, 100, _)), 28 | ] 29 | -------------------------------------------------------------------------------- /test/record-and-tuple.spec.ts: -------------------------------------------------------------------------------- 1 | import { IS_RECORD_TUPLE_SUPPORTED } from '../src/utils.js' 2 | 3 | import { execute } from './helpers.js' 4 | 5 | const proposal = 'record-and-tuple' 6 | 7 | test(proposal, async () => { 8 | expect(() => execute(proposal)).toThrowErrorMatchingSnapshot() 9 | if (IS_RECORD_TUPLE_SUPPORTED) { 10 | const module = await import('./record-and-tuple.js') 11 | // eslint-disable-next-line jest/no-conditional-expect 12 | expect(module.default).toEqual(['Record & Tuple proposal', 'tc39']) 13 | } 14 | }) 15 | -------------------------------------------------------------------------------- /test/record-and-tuple.ts: -------------------------------------------------------------------------------- 1 | const proposal = #{ 2 | id: 1234, 3 | title: 'Record & Tuple proposal', 4 | contents: `...`, 5 | // tuples are primitive types so you can put them in records: 6 | keywords: #['ecma', 'tc39', 'proposal', 'record', 'tuple'], 7 | } 8 | 9 | export default [proposal.title, proposal.keywords[1]] 10 | -------------------------------------------------------------------------------- /test/regexp-modifiers.spec.ts: -------------------------------------------------------------------------------- 1 | import { execute } from './helpers.js' 2 | import _ from './regexp-modifiers.js' 3 | 4 | const proposal = 'regexp-modifiers' 5 | 6 | test(proposal, () => { 7 | expect(() => execute(proposal)).toThrowErrorMatchingSnapshot() 8 | expect(_('Aa')).toEqual(true) 9 | expect(_('Ba')).toEqual(false) 10 | }) 11 | -------------------------------------------------------------------------------- /test/regexp-modifiers.ts: -------------------------------------------------------------------------------- 1 | const regex = /(?i:a)a/ 2 | 3 | export default (text: string) => regex.test(text) 4 | -------------------------------------------------------------------------------- /test/throw-expressions.spec.ts: -------------------------------------------------------------------------------- 1 | import { execute } from './helpers.js' 2 | import _ from './throw-expressions.js' 3 | 4 | const proposal = 'throw-expressions' 5 | 6 | test(proposal, () => { 7 | expect(() => execute(proposal)).toThrowErrorMatchingSnapshot() 8 | expect(() => _()).toThrow('Argument required') 9 | expect(_(proposal)).toBe(proposal) 10 | }) 11 | -------------------------------------------------------------------------------- /test/throw-expressions.ts: -------------------------------------------------------------------------------- 1 | export default (param = throw new TypeError('Argument required')) => param 2 | -------------------------------------------------------------------------------- /test/v8intrinsic.cjs: -------------------------------------------------------------------------------- 1 | /* istanbul ignore next */ 2 | function fn() { 3 | // do nothing 4 | } 5 | /* istanbul ignore next */ 6 | process.stdout.write(String(%GetOptimizationStatus(fn))) 7 | -------------------------------------------------------------------------------- /test/v8intrinsic.spec.ts: -------------------------------------------------------------------------------- 1 | import { execSync } from 'node:child_process' 2 | 3 | import { execute, resolve } from './helpers.js' 4 | 5 | const proposal = 'v8intrinsic' 6 | 7 | test(proposal, async () => { 8 | expect(() => execute(proposal + '.cjs')).toThrowErrorMatchingSnapshot() 9 | await expect( 10 | // @ts-expect-error 11 | import('./v8intrinsic.cjs'), 12 | ).rejects.toThrowErrorMatchingSnapshot() 13 | expect( 14 | execSync( 15 | `node --allow-natives-syntax ${resolve( 16 | proposal, 17 | // TODO: make `.ts` working again 18 | )}.cjs`, 19 | ).toString(), 20 | ).toBeDefined() 21 | }) 22 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "@1stg/tsconfig/node16", 3 | "compilerOptions": { 4 | "types": ["core-dts/src/proposals/stage-0", "jest", "node"] 5 | } 6 | } 7 | --------------------------------------------------------------------------------