diff --git a/.gitignore b/.gitignore
index fc31278c325de..a3ebac937fc66 100644
--- a/.gitignore
+++ b/.gitignore
@@ -2,6 +2,7 @@
build
build-module
build-style
+build-types
node_modules
gutenberg.zip
@@ -14,6 +15,7 @@ yarn.lock
playground/dist
.cache
+*.tsbuildinfo
# Report generated from jest-junit
test/native/junit.xml
diff --git a/.travis.yml b/.travis.yml
index 8a430251588a0..baf9a3bb3d431 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -114,6 +114,13 @@ jobs:
script:
- npx eslint --parser-options=ecmaVersion:5 --no-eslintrc --no-ignore ./build/**/*.js
+ - name: Typecheck
+ install:
+ - npm ci
+ script:
+ - npm run build:package-types
+
+
- name: Build artifacts
install:
# A "full" install is executed, since `npm ci` does not always exit
diff --git a/bin/packages/lint-staged-typecheck.js b/bin/packages/lint-staged-typecheck.js
new file mode 100644
index 0000000000000..579f154e3df34
--- /dev/null
+++ b/bin/packages/lint-staged-typecheck.js
@@ -0,0 +1,34 @@
+/**
+ * External dependencies
+ */
+const _ = require( 'lodash' );
+const path = require( 'path' );
+const fs = require( 'fs' );
+const execa = require( 'execa' );
+
+/* eslint-disable no-console */
+
+const repoRoot = path.join( __dirname, '..', '..' );
+const tscPath = path.join( repoRoot, 'node_modules', '.bin', 'tsc' );
+
+// lint-staged passes full paths to staged changes
+const changedFiles = process.argv.slice( 2 );
+
+// Transform changed files to package directories containing tsconfig.json
+const changedPackages = _.uniq(
+ changedFiles.map( ( fullPath ) => {
+ const relativePath = path.relative( repoRoot, fullPath );
+ return path.join( ...relativePath.split( path.sep ).slice( 0, 2 ) );
+ } )
+).filter( ( packageRoot ) =>
+ fs.existsSync( path.join( packageRoot, 'tsconfig.json' ) )
+);
+
+try {
+ execa.sync( tscPath, [ '--build', ...changedPackages ] );
+} catch ( err ) {
+ console.error( err.stdout );
+ process.exitCode = 1;
+}
+
+/* eslint-enable no-console */
diff --git a/bin/tsconfig.json b/bin/tsconfig.json
new file mode 100644
index 0000000000000..aab14da756163
--- /dev/null
+++ b/bin/tsconfig.json
@@ -0,0 +1,17 @@
+{
+ "extends": "../tsconfig.base.json",
+ "compilerOptions": {
+ "module": "commonjs",
+ "esModuleInterop": true,
+ "target": "ES6",
+ "lib": [ "ES6", "ES2020.string" ],
+ "rootDir": ".",
+ "declarationMap": false,
+
+ // We're not interested in the output, but we must generate
+ // something as part of a composite project. Use the
+ // ignored `.cache` file to hide tsbuildinfo and d.ts files.
+ "outDir": ".cache"
+ },
+ "files": [ "./api-docs/update-api-docs.js" ]
+}
diff --git a/package-lock.json b/package-lock.json
index a4184598a1d89..842c0fa0e00a5 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -10052,6 +10052,12 @@
"integrity": "sha512-Il2DtDVRGDcqjDtE+rF8iqg1CArehSK84HZJCT7AMITlyXRBpuPhqGLDQMowraqqu1coEaimg4ZOqggt6L6L+A==",
"dev": true
},
+ "@types/lodash": {
+ "version": "4.14.149",
+ "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.149.tgz",
+ "integrity": "sha512-ijGqzZt/b7BfzcK9vTrS6MFljQRPn5BFWOx8oE0GYxribu6uV+aA9zZuXI1zc/etK9E8nrgdoF2+LgUw7+9tJQ==",
+ "dev": true
+ },
"@types/minimatch": {
"version": "3.0.3",
"resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.3.tgz",
@@ -10087,6 +10093,12 @@
"integrity": "sha512-ce5d3q03Ex0sy4R14722Rmt6MT07Ua+k4FwDfdcToYJcMKNtRVQvJ6JCAPdAmAnbRb6CsX6aYb9m96NGod9uTw==",
"dev": true
},
+ "@types/qs": {
+ "version": "6.9.1",
+ "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.1.tgz",
+ "integrity": "sha512-lhbQXx9HKZAPgBkISrBcmAcMpZsmpe/Cd/hY7LGZS5OfkySUBItnPZHgQPssWYUET8elF+yCFBbP1Q0RZPTdaw==",
+ "dev": true
+ },
"@types/reach__router": {
"version": "1.2.6",
"resolved": "https://registry.npmjs.org/@types/reach__router/-/reach__router-1.2.6.tgz",
@@ -10140,6 +10152,12 @@
"integrity": "sha512-BnnRkgWYijCIndUn+LgoqKHX/hNpJC5G03B9y7mZya/C2gUQTSn75fEj3ZP1/Rl2E6EYeXh2/7/8UNEZ4X7HuQ==",
"dev": true
},
+ "@types/sprintf-js": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/@types/sprintf-js/-/sprintf-js-1.1.2.tgz",
+ "integrity": "sha512-hkgzYF+qnIl8uTO8rmUSVSfQ8BIfMXC4yJAF4n8BE758YsKBZvFC4NumnAegj7KmylP0liEZNpb9RRGFMbFejA==",
+ "dev": true
+ },
"@types/stack-utils": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-1.0.1.tgz",
@@ -39838,9 +39856,9 @@
"dev": true
},
"typescript": {
- "version": "3.5.3",
- "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.5.3.tgz",
- "integrity": "sha512-ACzBtm/PhXBDId6a6sDJfroT2pOWt/oOnk4/dElG5G33ZL776N3Y6/6bKZJBFpd+b05F3Ct9qDjMeJmRWtE2/g==",
+ "version": "3.8.3",
+ "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.8.3.tgz",
+ "integrity": "sha512-MYlEfn5VrLNsgudQTVJeNaQFUAI7DkhnOjdpAp4T+ku1TfQClewlbSuTVHiA+8skNBgaf02TL/kLOvig4y3G8w==",
"dev": true
},
"ua-parser-js": {
diff --git a/package.json b/package.json
index 61b182e0a1f67..097edf97aa642 100644
--- a/package.json
+++ b/package.json
@@ -86,7 +86,10 @@
"@storybook/addon-viewport": "5.3.2",
"@storybook/react": "5.3.2",
"@types/jest": "24.0.25",
+ "@types/lodash": "4.14.149",
+ "@types/qs": "6.9.1",
"@types/requestidlecallback": "0.3.1",
+ "@types/sprintf-js": "1.1.2",
"@wordpress/babel-plugin-import-jsx-pragma": "file:packages/babel-plugin-import-jsx-pragma",
"@wordpress/babel-plugin-makepot": "file:packages/babel-plugin-makepot",
"@wordpress/babel-preset-default": "file:packages/babel-preset-default",
@@ -167,16 +170,18 @@
"sprintf-js": "1.1.1",
"style-loader": "1.0.0",
"stylelint-config-wordpress": "13.1.0",
- "typescript": "3.5.3",
+ "typescript": "3.8.3",
"uuid": "3.3.2",
"webpack": "4.42.0",
"worker-farm": "1.7.0"
},
"scripts": {
"prebuild": "npm run check-engines",
- "clean:packages": "rimraf ./packages/*/build ./packages/*/build-module ./packages/*/build-style ./packages/*/node_modules",
+ "clean:packages": "rimraf \"./packages/*/@(build|build-module|build-style)\"",
+ "clean:package-types": "tsc --build --clean",
"prebuild:packages": "npm run clean:packages && lerna run build",
- "build:packages": "node ./bin/packages/build.js",
+ "build:packages": "npm run build:package-types && node ./bin/packages/build.js",
+ "build:package-types": "tsc --build",
"build": "npm run build:packages && wp-scripts build",
"check-engines": "wp-scripts check-engines",
"check-licenses": "concurrently \"wp-scripts check-licenses --prod --gpl2\" \"wp-scripts check-licenses --dev\"",
@@ -191,22 +196,21 @@
"fixtures:generate": "npm run fixtures:server-registered && cross-env GENERATE_MISSING_FIXTURES=y npm run test-unit",
"fixtures:regenerate": "npm run fixtures:clean && npm run fixtures:generate",
"format-js": "wp-scripts format-js",
- "lint": "concurrently \"npm run lint-js\" \"npm run lint-pkg-json\" \"npm run lint-css\" \"npm run lint-types\"",
+ "lint": "concurrently \"npm run lint-js\" \"npm run lint-pkg-json\" \"npm run lint-css\"",
"lint-js": "wp-scripts lint-js",
"lint-js:fix": "npm run lint-js -- --fix",
"lint-php": "npm run wp-env run composer run-script lint",
"lint-pkg-json": "wp-scripts lint-pkg-json . 'packages/*/package.json'",
"lint-css": "wp-scripts lint-style '**/*.scss'",
"lint-css:fix": "npm run lint-css -- --fix",
- "lint-types": "tsc",
"lint:md-js": "wp-scripts lint-md-js",
"lint:md-docs": "wp-scripts lint-md-docs",
"package-plugin": "./bin/build-plugin-zip.sh",
"pot-to-php": "./bin/pot-to-php.js",
"publish:check": "lerna updated",
- "publish:dev": "npm run build:packages && lerna publish --dist-tag next",
- "publish:legacy": "npm run build:packages && lerna publish --dist-tag legacy",
- "publish:prod": "npm run build:packages && lerna publish",
+ "publish:dev": "npm run clean:package-types && npm run build:packages && lerna publish --dist-tag next",
+ "publish:legacy": "npm run clean:package-types && npm run build:packages && lerna publish --dist-tag legacy",
+ "publish:prod": "npm run clean:package-types && npm run build:packages && lerna publish",
"test": "npm run lint && npm run test-unit",
"test-e2e": "wp-scripts test-e2e --config packages/e2e-tests/jest.config.js",
"test-e2e:watch": "npm run test-e2e -- --watch",
@@ -252,7 +256,8 @@
],
"packages/**/*.js": [
"node ./bin/api-docs/update-api-docs.js",
- "node ./bin/api-docs/are-api-docs-unstaged.js"
+ "node ./bin/api-docs/are-api-docs-unstaged.js",
+ "node ./bin/packages/lint-staged-typecheck.js"
]
},
"wp-env": {
diff --git a/packages/README.md b/packages/README.md
index 30cccbed973c4..af9be77ff1419 100644
--- a/packages/README.md
+++ b/packages/README.md
@@ -7,46 +7,44 @@ This repository uses [lerna] to manage WordPress modules and publish them as pac
When creating a new package, you need to provide at least the following:
1. `package.json` based on the template:
- ```json
- {
- "name": "@wordpress/package-name",
- "version": "1.0.0-beta.0",
- "description": "Package description.",
- "author": "The WordPress Contributors",
- "license": "GPL-2.0-or-later",
- "keywords": [
- "wordpress"
- ],
- "homepage": "https://github.com/WordPress/gutenberg/tree/master/packages/package-name/README.md",
- "repository": {
- "type": "git",
- "url": "https://github.com/WordPress/gutenberg.git"
- },
- "bugs": {
- "url": "https://github.com/WordPress/gutenberg/issues"
- },
- "main": "build/index.js",
- "module": "build-module/index.js",
- "react-native": "src/index",
- "dependencies": {
- "@babel/runtime": "^7.8.3"
- },
- "publishConfig": {
- "access": "public"
- }
- }
- ```
- This assumes that your code is located in the `src` folder and will be transpiled with `Babel`.
+ ```json
+ {
+ "name": "@wordpress/package-name",
+ "version": "1.0.0-beta.0",
+ "description": "Package description.",
+ "author": "The WordPress Contributors",
+ "license": "GPL-2.0-or-later",
+ "keywords": [ "wordpress" ],
+ "homepage": "https://github.com/WordPress/gutenberg/tree/master/packages/package-name/README.md",
+ "repository": {
+ "type": "git",
+ "url": "https://github.com/WordPress/gutenberg.git"
+ },
+ "bugs": {
+ "url": "https://github.com/WordPress/gutenberg/issues"
+ },
+ "main": "build/index.js",
+ "module": "build-module/index.js",
+ "react-native": "src/index",
+ "dependencies": {
+ "@babel/runtime": "^7.8.3"
+ },
+ "publishConfig": {
+ "access": "public"
+ }
+ }
+ ```
+ This assumes that your code is located in the `src` folder and will be transpiled with `Babel`.
2. `.npmrc` file which disables creating `package-lock.json` file for the package:
- ```
- package-lock=false
- ```
+ ```
+ package-lock=false
+ ```
3. `README.md` file containing at least:
- - Package name
- - Package description
- - Installation details
- - Usage example
- - `Code is Poetry` logo (`

`)
+ - Package name
+ - Package description
+ - Installation details
+ - Usage example
+ - `Code is Poetry` logo (`

`)
## Managing Dependencies
@@ -57,7 +55,7 @@ There are two types of dependencies that you might want to add to one of the exi
Production dependencies are stored in the `dependencies` section of the package’s `package.json` file.
#### Adding New Dependencies
-
+
The simplest way to add a production dependency to one of the packages is to run a very convenient [lerna add](https://github.com/lerna/lerna/tree/master/commands/add#readme) command from the root of the project.
_Example:_
@@ -91,9 +89,10 @@ Next, you need to run `npm install` in the root of the project to ensure that `p
#### Updating Existing Dependencies
This is the most confusing part of working with [lerna] which causes a lot of hassles for contributors. The most successful strategy so far is to do the following:
- 1. First, remove the existing dependency as described in the previous section.
- 2. Next, add the same dependency back as described in the first section of this chapter. This time it wil get the latest version applied unless you enforce a different version explicitly.
-
+
+1. First, remove the existing dependency as described in the previous section.
+2. Next, add the same dependency back as described in the first section of this chapter. This time it wil get the latest version applied unless you enforce a different version explicitly.
+
### Development Dependencies
In contrast to production dependencies, development dependencies shouldn't be stored in individual WordPress packages. Instead they should be installed in the project's `package.json` file using the usual `npm install` command. In effect, all development tools are configured to work with every package at the same time to ensure they share the same characteristics and integrate correctly with each other.
@@ -119,16 +118,16 @@ _Example:_
### Bug Fix
-- Fixed an off-by-one error with the `sum` function.
+- Fixed an off-by-one error with the `sum` function.
```
There are a number of common release subsections you can follow. Each is intended to align to a specific meaning in the context of the [Semantic Versioning (`semver`) specification](https://semver.org/) the project adheres to. It is important that you describe your changes accurately, since this is used in the packages release process to help determine the version of the next release.
-- "Breaking Change" - A backwards-incompatible change which requires specific attention of the impacted developers to reconcile (requires a major version bump).
-- "New Feature" - The addition of a new backwards-compatible function or feature to the existing public API (requires a minor verison bump).
-- "Enhancement" - Backwards-compatible improvements to existing functionality (requires a minor version bump).
-- "Bug Fix" - Resolutions to existing buggy behavior (requires a patch version bump).
-- "Internal" - Changes which do not have an impact on the public interface or behavior of the module (requires a patch version bump).
+- "Breaking Change" - A backwards-incompatible change which requires specific attention of the impacted developers to reconcile (requires a major version bump).
+- "New Feature" - The addition of a new backwards-compatible function or feature to the existing public API (requires a minor verison bump).
+- "Enhancement" - Backwards-compatible improvements to existing functionality (requires a minor version bump).
+- "Bug Fix" - Resolutions to existing buggy behavior (requires a patch version bump).
+- "Internal" - Changes which do not have an impact on the public interface or behavior of the module (requires a patch version bump).
While other section naming can be used when appropriate, it's important that are expressed clearly to avoid confusion for both the packages releaser and third-party consumers.
@@ -190,5 +189,61 @@ npm run publish:legacy
This is usually necessary when adding bug fixes or security patches to the earlier versions of WordPress.
+## TypeScript
+
+The [TypeScript](http://www.typescriptlang.org/) language is a typed superset of JavaScript that compiles to plain JavaScript.
+Gutenberg does not use the TypeScript language, however TypeScript has powerful tooling that can be applied to JavaScript projects.
+
+Gutenberg uses TypeScript for several reasons, including:
+
+- Powerful editor integrations improve developer experience.
+- Type system can detect some issues and lead to more robust software.
+- Type declarations can be produced to allow other projects to benefit from these advantages as well.
+
+### Using TypeScript
+
+Gutenberg uses TypeScript by running the TypeScript compiler (`tsc`) on select packages.
+These packages benefit from type checking and produced type declarations in the published packages.
+
+To opt-in to TypeScript tooling, packages should include a `tsconfig.json` file in the package root and add an entry to the root `tsconfig.json` references.
+The changes will indicate that the package has opted-in and will be included in the TypeScript build process.
+
+A `tsconfig.json` file should look like the following (comments are not necessary):
+
+```jsonc
+{
+ // Extends a base configuration common to most packages
+ "extends": "../../tsconfig.base.json",
+
+ // Options for the TypeScript compiler
+ // We'll usually set our `rootDir` and `declarationDir` as follows, which is specific
+ // to each project.
+ "compilerOptions": {
+ "rootDir": "src",
+ "declarationDir": "build-types"
+ },
+
+ // Which source files should be included
+ "include": [ "src/**/*" ],
+
+ // Other WordPress package dependencies that have opted-in to TypeScript should be listed
+ // here. In this case, our package depends on `@wordpress/dom-ready`.
+ "references": [ { "path": "../dom-ready" } ]
+}
+```
+
+Type declarations will be produced in the `build-types` which should be included in the published package.
+For consumers to use the published type declarations, we'll set the `types` field in `package.json`:
+
+```json
+{
+ "main": "build/index.js",
+ "main-module": "build-module/index.js",
+ "types": "build-types"
+}
+```
+
+Ensure that the `build-types` directory will be included in the published package, for example if a `files` field is declared.
+
[lerna]: https://lerna.js.org/
[npm]: https://www.npmjs.com/
diff --git a/packages/a11y/CHANGELOG.md b/packages/a11y/CHANGELOG.md
index 6d3354f059cc8..b1c90b9bd0c75 100644
--- a/packages/a11y/CHANGELOG.md
+++ b/packages/a11y/CHANGELOG.md
@@ -1,3 +1,9 @@
+## Master
+
+### New feature
+
+- Include TypeScript type declarations ([#18942](https://github.com/WordPress/gutenberg/pull/18942))
+
## 2.0.0 (2018-09-05)
### Breaking Change
diff --git a/packages/a11y/package.json b/packages/a11y/package.json
index 3f2dc80ae2090..800fbeee1c28d 100644
--- a/packages/a11y/package.json
+++ b/packages/a11y/package.json
@@ -21,6 +21,7 @@
"main": "build/index.js",
"module": "build-module/index.js",
"react-native": "src/index",
+ "types": "build-types",
"dependencies": {
"@babel/runtime": "^7.8.3",
"@wordpress/dom-ready": "file:../dom-ready"
diff --git a/packages/a11y/tsconfig.json b/packages/a11y/tsconfig.json
new file mode 100644
index 0000000000000..1a0a90bc8cb58
--- /dev/null
+++ b/packages/a11y/tsconfig.json
@@ -0,0 +1,9 @@
+{
+ "extends": "../../tsconfig.base.json",
+ "compilerOptions": {
+ "rootDir": "src",
+ "declarationDir": "build-types"
+ },
+ "references": [ { "path": "../dom-ready" } ],
+ "include": [ "src/**/*" ]
+}
diff --git a/packages/blob/CHANGELOG.md b/packages/blob/CHANGELOG.md
index 1288967c3cfdb..03731fb72850f 100644
--- a/packages/blob/CHANGELOG.md
+++ b/packages/blob/CHANGELOG.md
@@ -1,3 +1,9 @@
+## Master
+
+### New feature
+
+- Include TypeScript type declarations ([#18942](https://github.com/WordPress/gutenberg/pull/18942))
+
## 2.1.0 (2018-10-19)
### New Features
diff --git a/packages/blob/package.json b/packages/blob/package.json
index 86a19462a1e21..238b7cfcd8827 100644
--- a/packages/blob/package.json
+++ b/packages/blob/package.json
@@ -20,6 +20,7 @@
"main": "build/index.js",
"module": "build-module/index.js",
"react-native": "src/index",
+ "types": "build-types",
"sideEffects": false,
"dependencies": {
"@babel/runtime": "^7.8.3"
diff --git a/packages/blob/tsconfig.json b/packages/blob/tsconfig.json
new file mode 100644
index 0000000000000..3c2c31f506f13
--- /dev/null
+++ b/packages/blob/tsconfig.json
@@ -0,0 +1,8 @@
+{
+ "extends": "../../tsconfig.base.json",
+ "compilerOptions": {
+ "rootDir": "src",
+ "declarationDir": "build-types"
+ },
+ "include": [ "src/**/*" ]
+}
diff --git a/packages/dom-ready/CHANGELOG.md b/packages/dom-ready/CHANGELOG.md
index 116d21d37d421..1d18cce33a0aa 100644
--- a/packages/dom-ready/CHANGELOG.md
+++ b/packages/dom-ready/CHANGELOG.md
@@ -1,3 +1,9 @@
+## Master
+
+### New feature
+
+- Include TypeScript type declarations ([#18942](https://github.com/WordPress/gutenberg/pull/18942))
+
## 2.0.0 (2018-09-05)
### Breaking Change
diff --git a/packages/dom-ready/package.json b/packages/dom-ready/package.json
index 6fd51bdd0b714..422e0e8376b4d 100644
--- a/packages/dom-ready/package.json
+++ b/packages/dom-ready/package.json
@@ -20,6 +20,7 @@
"main": "build/index.js",
"module": "build-module/index.js",
"react-native": "src/index",
+ "types": "build-types",
"sideEffects": false,
"dependencies": {
"@babel/runtime": "^7.8.3"
diff --git a/packages/dom-ready/tsconfig.json b/packages/dom-ready/tsconfig.json
new file mode 100644
index 0000000000000..3c2c31f506f13
--- /dev/null
+++ b/packages/dom-ready/tsconfig.json
@@ -0,0 +1,8 @@
+{
+ "extends": "../../tsconfig.base.json",
+ "compilerOptions": {
+ "rootDir": "src",
+ "declarationDir": "build-types"
+ },
+ "include": [ "src/**/*" ]
+}
diff --git a/packages/eslint-plugin/configs/jsdoc.js b/packages/eslint-plugin/configs/jsdoc.js
index ca3ae01de8d4c..8bff4a36b7d32 100644
--- a/packages/eslint-plugin/configs/jsdoc.js
+++ b/packages/eslint-plugin/configs/jsdoc.js
@@ -47,6 +47,7 @@ const typescriptUtilityTypes = [
'IterableIterator',
'NonNullable',
'Omit',
+ 'Parameters',
'Partial',
'Pick',
'PromiseLike',
diff --git a/packages/i18n/CHANGELOG.md b/packages/i18n/CHANGELOG.md
index 700b3b520eefb..e9b5255dae532 100644
--- a/packages/i18n/CHANGELOG.md
+++ b/packages/i18n/CHANGELOG.md
@@ -2,7 +2,9 @@
### New Feature
-- Add `isRTL` function (#20298)
+- Add `isRTL` function ([#20298](https://github.com/WordPress/gutenberg/pull/20298))
+- Include TypeScript type declarations ([#18942](https://github.com/WordPress/gutenberg/pull/18942))
+
## 3.1.0 (2018-11-15)
diff --git a/packages/i18n/package.json b/packages/i18n/package.json
index a328ecf0959d0..ce5ef62a0b654 100644
--- a/packages/i18n/package.json
+++ b/packages/i18n/package.json
@@ -20,6 +20,7 @@
"main": "build/index.js",
"module": "build-module/index.js",
"react-native": "src/index",
+ "types": "build-types",
"bin": {
"pot-to-php": "./tools/pot-to-php.js"
},
diff --git a/packages/i18n/src/index.js b/packages/i18n/src/index.js
index aa7a2d059f8a6..111ea03e55571 100644
--- a/packages/i18n/src/index.js
+++ b/packages/i18n/src/index.js
@@ -17,7 +17,10 @@ import sprintfjs from 'sprintf-js';
*/
const DEFAULT_LOCALE_DATA = {
'': {
- plural_forms: ( n ) => ( n === 1 ? 0 : 1 ),
+ /** @param {number} n */
+ plural_forms( n ) {
+ return n === 1 ? 0 : 1;
+ },
},
};
diff --git a/packages/i18n/tsconfig.json b/packages/i18n/tsconfig.json
new file mode 100644
index 0000000000000..cccd60dd6447e
--- /dev/null
+++ b/packages/i18n/tsconfig.json
@@ -0,0 +1,9 @@
+{
+ "extends": "../../tsconfig.base.json",
+ "compilerOptions": {
+ "noImplicitAny": false,
+ "rootDir": "src",
+ "declarationDir": "build-types"
+ },
+ "include": [ "src/**/*" ]
+}
diff --git a/packages/is-shallow-equal/CHANGELOG.md b/packages/is-shallow-equal/CHANGELOG.md
index 17019daee1ea6..4eb1d049e0079 100644
--- a/packages/is-shallow-equal/CHANGELOG.md
+++ b/packages/is-shallow-equal/CHANGELOG.md
@@ -1,3 +1,15 @@
+## Master
+
+### Breaking change
+
+- Restructure package moving source files into `lib` directory. Direct imports of
+ `@wordpress/is-shallow-equal/arrays` and `@wordpress/is-shallow-equal/objects` were never
+ officially supported and have been removed. ([#18942](https://github.com/WordPress/gutenberg/pull/18942))
+
+### New feature
+
+- Include TypeScript type declarations ([#18942](https://github.com/WordPress/gutenberg/pull/18942))
+
## 1.5.0 (2019-08-05)
### Bug Fixes
diff --git a/packages/is-shallow-equal/benchmark/index.js b/packages/is-shallow-equal/benchmark/index.js
index 5506e53206e12..5779f87688eae 100644
--- a/packages/is-shallow-equal/benchmark/index.js
+++ b/packages/is-shallow-equal/benchmark/index.js
@@ -16,10 +16,10 @@ const afterArrayUnequal = [ 1, 2, 3, 4, 5, 'Unequal', 7 ];
[
[
'@wordpress/is-shallow-equal (type specific)',
- require( '../objects' ),
- require( '../arrays' ),
+ require( '..' ).isShallowEqualObjects,
+ require( '..' ).isShallowEqualArrays,
],
- [ '@wordpress/is-shallow-equal', require( '../' ) ],
+ [ '@wordpress/is-shallow-equal', require( '..' ) ],
[ 'shallowequal', require( 'shallowequal' ) ],
[
'shallow-equal (type specific)',
diff --git a/packages/is-shallow-equal/arrays.js b/packages/is-shallow-equal/lib/arrays.js
similarity index 100%
rename from packages/is-shallow-equal/arrays.js
rename to packages/is-shallow-equal/lib/arrays.js
diff --git a/packages/is-shallow-equal/index.js b/packages/is-shallow-equal/lib/index.js
similarity index 100%
rename from packages/is-shallow-equal/index.js
rename to packages/is-shallow-equal/lib/index.js
diff --git a/packages/is-shallow-equal/objects.js b/packages/is-shallow-equal/lib/objects.js
similarity index 100%
rename from packages/is-shallow-equal/objects.js
rename to packages/is-shallow-equal/lib/objects.js
diff --git a/packages/is-shallow-equal/package.json b/packages/is-shallow-equal/package.json
index 0800bdb4e7543..32219eda44981 100644
--- a/packages/is-shallow-equal/package.json
+++ b/packages/is-shallow-equal/package.json
@@ -20,11 +20,12 @@
"url": "https://github.com/WordPress/gutenberg/issues"
},
"files": [
- "arrays.js",
- "index.js",
- "objects.js"
+ "lib",
+ "build-types",
+ "*.md"
],
- "main": "index.js",
+ "main": "lib/index.js",
+ "types": "build-types",
"sideEffects": false,
"dependencies": {
"@babel/runtime": "^7.8.3"
diff --git a/packages/is-shallow-equal/test/index.js b/packages/is-shallow-equal/test/index.js
index 3ec86ed352928..66bf538552c64 100644
--- a/packages/is-shallow-equal/test/index.js
+++ b/packages/is-shallow-equal/test/index.js
@@ -1,9 +1,10 @@
/**
* Internal dependencies
*/
-import isShallowEqual from '../';
-import isShallowEqualArrays from '../arrays';
-import isShallowEqualObjects from '../objects';
+import isShallowEqual, {
+ isShallowEqualArrays,
+ isShallowEqualObjects,
+} from '..';
describe( 'isShallowEqual', () => {
it( 'returns false if of different types', () => {
diff --git a/packages/is-shallow-equal/tsconfig.json b/packages/is-shallow-equal/tsconfig.json
new file mode 100644
index 0000000000000..426ab13d0aa8f
--- /dev/null
+++ b/packages/is-shallow-equal/tsconfig.json
@@ -0,0 +1,8 @@
+{
+ "extends": "../../tsconfig.base.json",
+ "compilerOptions": {
+ "rootDir": "lib",
+ "declarationDir": "build-types"
+ },
+ "include": [ "lib/**/*" ]
+}
diff --git a/packages/npm-package-json-lint-config/CHANGELOG.md b/packages/npm-package-json-lint-config/CHANGELOG.md
index 945e31866bbe8..c00529998a1ff 100644
--- a/packages/npm-package-json-lint-config/CHANGELOG.md
+++ b/packages/npm-package-json-lint-config/CHANGELOG.md
@@ -1,6 +1,12 @@
+## Master
+
+### Breaking Change
+
+- Add `types` to the order of preferred properties. ([#18942](https://github.com/WordPress/gutenberg/pull/18942))
+
## 2.0.0 (2019-06-12)
-### Braking Change
+### Breaking Change
- Added `type` and `react-native` to the order of preferred properties.
diff --git a/packages/npm-package-json-lint-config/index.js b/packages/npm-package-json-lint-config/index.js
index e8fbd3eebdcec..831970c59bf3a 100644
--- a/packages/npm-package-json-lint-config/index.js
+++ b/packages/npm-package-json-lint-config/index.js
@@ -57,6 +57,7 @@ const defaultConfig = {
'main',
'module',
'react-native',
+ 'types',
'bin',
'dependencies',
'devDependencies',
diff --git a/packages/priority-queue/CHANGELOG.md b/packages/priority-queue/CHANGELOG.md
index e4a76269c9ca8..9232755f3aa4d 100644
--- a/packages/priority-queue/CHANGELOG.md
+++ b/packages/priority-queue/CHANGELOG.md
@@ -1,5 +1,9 @@
## Master
+### New feature
+
+- Include TypeScript type declarations ([#18942](https://github.com/WordPress/gutenberg/pull/18942))
+
## 1.5.0 (2020-02-04)
### Bug Fixes
diff --git a/packages/priority-queue/package.json b/packages/priority-queue/package.json
index 955bbbd161f18..8e18f3158c896 100644
--- a/packages/priority-queue/package.json
+++ b/packages/priority-queue/package.json
@@ -21,6 +21,7 @@
"main": "build/index.js",
"module": "build-module/index.js",
"react-native": "src/index",
+ "types": "build-types",
"sideEffects": false,
"dependencies": {
"@babel/runtime": "^7.8.3"
diff --git a/packages/priority-queue/src/index.js b/packages/priority-queue/src/index.js
index de82a4296e947..560ca7b5f4a3e 100644
--- a/packages/priority-queue/src/index.js
+++ b/packages/priority-queue/src/index.js
@@ -71,8 +71,6 @@ export const createQueue = () => {
/**
* Callback to process as much queue as time permits.
*
- * @type {IdleRequestCallback & FrameRequestCallback}
- *
* @param {IdleDeadline|number} deadline Idle callback deadline object, or
* animation frame timestamp.
*/
diff --git a/packages/priority-queue/src/request-idle-callback.js b/packages/priority-queue/src/request-idle-callback.js
index b147c9ad86638..64b51e7d2b336 100644
--- a/packages/priority-queue/src/request-idle-callback.js
+++ b/packages/priority-queue/src/request-idle-callback.js
@@ -1,5 +1,9 @@
/**
- * @return {typeof window.requestIdleCallback|typeof window.requestAnimationFrame|((callback:(timestamp:number)=>void)=>void)} RequestIdleCallback
+ * @typedef {( timeOrDeadline: IdleDeadline | number ) => void} Callback
+ */
+
+/**
+ * @return {(callback: Callback) => void} RequestIdleCallback
*/
export function createRequestIdleCallback() {
if ( typeof window === 'undefined' ) {
diff --git a/packages/priority-queue/tsconfig.json b/packages/priority-queue/tsconfig.json
new file mode 100644
index 0000000000000..3c2c31f506f13
--- /dev/null
+++ b/packages/priority-queue/tsconfig.json
@@ -0,0 +1,8 @@
+{
+ "extends": "../../tsconfig.base.json",
+ "compilerOptions": {
+ "rootDir": "src",
+ "declarationDir": "build-types"
+ },
+ "include": [ "src/**/*" ]
+}
diff --git a/packages/project-management-automation/CHANGELOG.md b/packages/project-management-automation/CHANGELOG.md
index 2c2284ae8eebf..c7363d0d38510 100644
--- a/packages/project-management-automation/CHANGELOG.md
+++ b/packages/project-management-automation/CHANGELOG.md
@@ -1,3 +1,9 @@
+## Master
+
+### New feature
+
+- Include TypeScript type declarations ([#18942](https://github.com/WordPress/gutenberg/pull/18942))
+
## 1.0.0 (2019-08-29)
- Initial release.
diff --git a/packages/project-management-automation/lib/if-not-fork.js b/packages/project-management-automation/lib/if-not-fork.js
index 5c8e65adb4d9d..7ab214026cf8b 100644
--- a/packages/project-management-automation/lib/if-not-fork.js
+++ b/packages/project-management-automation/lib/if-not-fork.js
@@ -15,6 +15,7 @@ const debug = require( './debug' );
* @return {WPAutomationTask} Enhanced task.
*/
function ifNotFork( handler ) {
+ /** @type {WPAutomationTask} */
const newHandler = ( payload, octokit ) => {
if (
payload.pull_request.head.repo.full_name ===
diff --git a/packages/project-management-automation/package.json b/packages/project-management-automation/package.json
index 3e41185ada8c0..4e1d7bcf3e368 100644
--- a/packages/project-management-automation/package.json
+++ b/packages/project-management-automation/package.json
@@ -17,6 +17,7 @@
"url": "https://github.com/WordPress/gutenberg/issues"
},
"main": "lib/index.js",
+ "types": "build-types",
"dependencies": {
"@actions/core": "^1.0.0",
"@actions/github": "^1.0.0",
diff --git a/packages/project-management-automation/tsconfig.json b/packages/project-management-automation/tsconfig.json
new file mode 100644
index 0000000000000..395281ecb0e72
--- /dev/null
+++ b/packages/project-management-automation/tsconfig.json
@@ -0,0 +1,11 @@
+{
+ "extends": "../../tsconfig.base.json",
+ "compilerOptions": {
+ "rootDir": "lib",
+ "declarationDir": "build-types",
+
+ // This is required due to a type error coming from missing types in @actions/github
+ "noImplicitAny": false
+ },
+ "include": [ "lib/**/*" ]
+}
diff --git a/packages/token-list/CHANGELOG.md b/packages/token-list/CHANGELOG.md
index 4f09e8ebd8395..48bb8d1722464 100644
--- a/packages/token-list/CHANGELOG.md
+++ b/packages/token-list/CHANGELOG.md
@@ -1,3 +1,9 @@
+## Master
+
+### New feature
+
+- Include TypeScript type declarations ([#18942](https://github.com/WordPress/gutenberg/pull/18942))
+
## 1.1.0 (2018-11-20)
### Enhancements
diff --git a/packages/token-list/package.json b/packages/token-list/package.json
index 2e7947df9e8f5..65aaa92b9a718 100644
--- a/packages/token-list/package.json
+++ b/packages/token-list/package.json
@@ -19,6 +19,7 @@
"main": "build/index.js",
"module": "build-module/index.js",
"react-native": "src/index",
+ "types": "build-types",
"dependencies": {
"@babel/runtime": "^7.8.3",
"lodash": "^4.17.15"
diff --git a/packages/token-list/src/index.js b/packages/token-list/src/index.js
index 08f63abfa2612..41f84b47fcc92 100644
--- a/packages/token-list/src/index.js
+++ b/packages/token-list/src/index.js
@@ -17,11 +17,49 @@ export default class TokenList {
constructor( initialValue = '' ) {
this.value = initialValue;
- [ 'entries', 'forEach', 'keys', 'values' ].forEach( ( fn ) => {
- this[ fn ] = ( ...args ) => this._valueAsArray[ fn ]( ...args );
- } );
+ // Disable reason: These are type hints on the class.
+ /* eslint-disable no-unused-expressions */
+ /** @type {string} */
+ this._currentValue;
+
+ /** @type {string[]} */
+ this._valueAsArray;
+ /* eslint-enable no-unused-expressions */
}
+ // Disable reason: JSDoc lint doesn't understand TypeScript types
+ /* eslint-disable jsdoc/valid-types */
+
+ /**
+ * @param {Parameters['entries']>} args
+ */
+ entries( ...args ) {
+ return this._valueAsArray.entries( ...args );
+ }
+
+ /**
+ * @param {Parameters['forEach']>} args
+ */
+ forEach( ...args ) {
+ return this._valueAsArray.forEach( ...args );
+ }
+
+ /**
+ * @param {Parameters['keys']>} args
+ */
+ keys( ...args ) {
+ return this._valueAsArray.keys( ...args );
+ }
+
+ /**
+ * @param {Parameters['values']>} args
+ */
+ values( ...args ) {
+ return this._valueAsArray.values( ...args );
+ }
+
+ /* eslint-enable jsdoc/valid-types */
+
/**
* Returns the associated set as string.
*
diff --git a/packages/token-list/tsconfig.json b/packages/token-list/tsconfig.json
new file mode 100644
index 0000000000000..e22ff86abb6f2
--- /dev/null
+++ b/packages/token-list/tsconfig.json
@@ -0,0 +1,8 @@
+{
+ "extends": "../../tsconfig.base.json",
+ "compilerOptions": {
+ "rootDir": "src",
+ "outDir": "build-types"
+ },
+ "include": [ "src/**/*" ]
+}
diff --git a/packages/url/CHANGELOG.md b/packages/url/CHANGELOG.md
index 2845b6c35e4ac..bf543a6242284 100644
--- a/packages/url/CHANGELOG.md
+++ b/packages/url/CHANGELOG.md
@@ -1,5 +1,9 @@
## Master
+### New feature
+
+- Include TypeScript type declarations ([#18942](https://github.com/WordPress/gutenberg/pull/18942))
+
### Bug Fixes
- `getQueryString` now correctly considers hash fragments when considering whether to return a query string. Previously, `getQueryString( 'https://example.com/#?foo' )` would wrongly return `'foo'` as its result. A hash fragment is always the last segment of a URL, and the querystring must always precede it ([see reference specification](https://url.spec.whatwg.org/#absolute-url-with-fragment-string)).
diff --git a/packages/url/package.json b/packages/url/package.json
index c564a35d316e1..23417710b2ffc 100644
--- a/packages/url/package.json
+++ b/packages/url/package.json
@@ -20,6 +20,7 @@
"main": "build/index.js",
"module": "build-module/index.js",
"react-native": "src/index",
+ "types": "build-types",
"sideEffects": false,
"dependencies": {
"@babel/runtime": "^7.8.3",
diff --git a/packages/url/tsconfig.json b/packages/url/tsconfig.json
new file mode 100644
index 0000000000000..70efdfe49990d
--- /dev/null
+++ b/packages/url/tsconfig.json
@@ -0,0 +1,11 @@
+{
+ "extends": "../../tsconfig.base.json",
+ "compilerOptions": {
+ "rootDir": "src",
+ "declarationDir": "build-types",
+
+ // This is required because the `react-native-url-polyfill` dependency lacks types
+ "noImplicitAny": false
+ },
+ "include": [ "src/**/*" ]
+}
diff --git a/packages/warning/CHANGELOG.md b/packages/warning/CHANGELOG.md
index 15517d8f1ce7c..e6a9454a3e0ff 100644
--- a/packages/warning/CHANGELOG.md
+++ b/packages/warning/CHANGELOG.md
@@ -1,5 +1,9 @@
## Master
+### New feature
+
+- Include TypeScript type declarations ([#18942](https://github.com/WordPress/gutenberg/pull/18942))
+
## 1.0.0 (2020-02-04)
Initial release.
diff --git a/packages/warning/package.json b/packages/warning/package.json
index fd94779db9e83..ebe83bb4221e6 100644
--- a/packages/warning/package.json
+++ b/packages/warning/package.json
@@ -20,6 +20,7 @@
"main": "build/index.js",
"module": "build-module/index.js",
"react-native": "src/index",
+ "types": "build-types",
"sideEffects": false,
"publishConfig": {
"access": "public"
diff --git a/packages/warning/tsconfig.json b/packages/warning/tsconfig.json
new file mode 100644
index 0000000000000..3c2c31f506f13
--- /dev/null
+++ b/packages/warning/tsconfig.json
@@ -0,0 +1,8 @@
+{
+ "extends": "../../tsconfig.base.json",
+ "compilerOptions": {
+ "rootDir": "src",
+ "declarationDir": "build-types"
+ },
+ "include": [ "src/**/*" ]
+}
diff --git a/tsconfig.base.json b/tsconfig.base.json
new file mode 100644
index 0000000000000..8ee1f8b3d415b
--- /dev/null
+++ b/tsconfig.base.json
@@ -0,0 +1,35 @@
+{
+ "compilerOptions": {
+ "allowJs": true,
+ "checkJs": true,
+ "allowSyntheticDefaultImports": true,
+ "jsx": "preserve",
+ "target": "esnext",
+ "module": "esnext",
+ "lib": [ "dom", "esnext" ],
+ "declaration": true,
+ "declarationMap": true,
+ "composite": true,
+ "emitDeclarationOnly": true,
+ "isolatedModules": true,
+
+ /* Strict Type-Checking Options */
+ "strict": true,
+ "strictNullChecks": true,
+ "noImplicitAny": true,
+
+ /* Additional Checks */
+ "noUnusedLocals": true,
+ "noUnusedParameters": true,
+ "noImplicitReturns": true,
+ "noFallthroughCasesInSwitch": true,
+
+ /* Module Resolution Options */
+ "moduleResolution": "node",
+
+ /* This needs to be false so our types are possible to consume without setting this */
+ "esModuleInterop": false,
+ "resolveJsonModule": true
+ },
+ "exclude": [ "**/benchmark", "**/test/**", "**/build/**", "**/build-*/**" ]
+}
diff --git a/tsconfig.json b/tsconfig.json
index d470e66c01e3c..d5c7494798745 100644
--- a/tsconfig.json
+++ b/tsconfig.json
@@ -1,52 +1,16 @@
{
- "compilerOptions": {
- "allowJs": true,
- "allowSyntheticDefaultImports": true,
- "checkJs": true,
- "jsx": "preserve",
- "lib": ["dom", "esnext", "es2020.string"],
- "module": "commonjs",
- "noEmit": true,
- "resolveJsonModule": true,
- "target": "esnext",
-
- /* Project Imports */
- "baseUrl": ".",
- "paths": {
- "@wordpress/*": [
- "packages/*/index.js",
- "packages/*/src/index.js"
- ]
- },
-
- /* Strict Type-Checking Options */
- "strict": true, /* Enable all strict type-checking options. */
- "strictNullChecks": true,
- "noImplicitAny": false, /* Raise error on expressions and declarations with an implied 'any' type. */
-
- /* Additional Checks */
- "noUnusedLocals": true, /* Report errors on unused locals. */
- "noUnusedParameters": true, /* Report errors on unused parameters. */
- "noImplicitReturns": true, /* Report error when not all code paths in function return a value. */
- "noFallthroughCasesInSwitch": true, /* Report errors for fallthrough cases in switch statement. */
- },
- "include": [
- "./bin/api-docs/update-api-docs.js",
- "./packages/a11y/**/*.js",
- "./packages/blob/**/*.js",
- "./packages/dom-ready/**/*.js",
- "./packages/i18n/**/*.js",
- "./packages/is-shallow-equal/**/*.js",
- "./packages/priority-queue/**/*.js",
- "./packages/project-management-automation/**/*.js",
- "./packages/token-list/**/*.js",
- "./packages/url/src/**/*.js",
- "./packages/warning/**/*.js",
+ "references": [
+ { "path": "bin" },
+ { "path": "packages/a11y" },
+ { "path": "packages/blob" },
+ { "path": "packages/dom-ready" },
+ { "path": "packages/i18n" },
+ { "path": "packages/is-shallow-equal" },
+ { "path": "packages/priority-queue" },
+ { "path": "packages/project-management-automation" },
+ { "path": "packages/token-list" },
+ { "path": "packages/url" },
+ { "path": "packages/warning" }
],
- "exclude": [
- "./packages/*/benchmark",
- "./packages/**/test/**",
- "./packages/**/build/**",
- "./packages/**/build-module/**"
- ]
+ "files": []
}