diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 251d8a9c08df..d392328c114a 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -219,3 +219,25 @@ jobs: with: name: playwright-report path: .playwright + + typecheck: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - name: Use Node.js 16.x + uses: actions/setup-node@v3 + with: + node-version: '16.x' + - uses: actions/cache@v3 + id: cache + with: + path: | + node_modules + */**/node_modules + key: ${{ runner.os }}-yarn-${{ hashFiles('**/yarn.lock') }} + - name: Install dependencies + run: yarn install --immutable --immutable-cache + - name: Build project + run: yarn build --ignore '@carbon/sketch' + - name: Typecheck TypeScript files + run: yarn typecheck \ No newline at end of file diff --git a/.gitignore b/.gitignore index b80070cd9600..1fe2131dd27e 100644 --- a/.gitignore +++ b/.gitignore @@ -57,3 +57,6 @@ package-lock.json # Playwright .playwright + +# TypeScript +tsconfig.tsbuildinfo diff --git a/.yarn/cache/typescript-npm-4.7.2-82fa810e5c-5163585e6b.zip b/.yarn/cache/typescript-npm-4.7.2-82fa810e5c-5163585e6b.zip deleted file mode 100644 index 7dbcf0a5b0a8..000000000000 Binary files a/.yarn/cache/typescript-npm-4.7.2-82fa810e5c-5163585e6b.zip and /dev/null differ diff --git a/.yarn/cache/typescript-npm-4.8.2-a4828fa7ad-7f5b81d0d5.zip b/.yarn/cache/typescript-npm-4.8.2-a4828fa7ad-7f5b81d0d5.zip new file mode 100644 index 000000000000..fed6b078bb15 Binary files /dev/null and b/.yarn/cache/typescript-npm-4.8.2-a4828fa7ad-7f5b81d0d5.zip differ diff --git a/.yarn/cache/typescript-patch-071c93e06e-6f49363af8.zip b/.yarn/cache/typescript-patch-071c93e06e-6f49363af8.zip new file mode 100644 index 000000000000..d038704c56d0 Binary files /dev/null and b/.yarn/cache/typescript-patch-071c93e06e-6f49363af8.zip differ diff --git a/.yarn/cache/typescript-patch-387d77a6ef-7e2b9a9f4a.zip b/.yarn/cache/typescript-patch-387d77a6ef-7e2b9a9f4a.zip deleted file mode 100644 index 851b1d55558e..000000000000 Binary files a/.yarn/cache/typescript-patch-387d77a6ef-7e2b9a9f4a.zip and /dev/null differ diff --git a/package.json b/package.json index 5852cf9cbeb4..4add59d6784d 100644 --- a/package.json +++ b/package.json @@ -26,6 +26,7 @@ "sync": "carbon-cli sync", "test": "cross-env BABEL_ENV=test jest", "test:e2e": "cross-env BABEL_ENV=test jest -c jest.e2e.config.js", + "typecheck": "tsc -b", "postinstall": "husky install" }, "resolutions": { @@ -73,7 +74,8 @@ "react": "^17.0.2", "react-dom": "^17.0.2", "rimraf": "^3.0.0", - "stylelint": "^14.3.0" + "stylelint": "^14.3.0", + "typescript": "^4.7.2" }, "commitlint": { "extends": [ diff --git a/packages/icon-build-helpers/src/builders/react/next.js b/packages/icon-build-helpers/src/builders/react/next.js index a936276726a4..a1ae576988be 100644 --- a/packages/icon-build-helpers/src/builders/react/next.js +++ b/packages/icon-build-helpers/src/builders/react/next.js @@ -195,6 +195,18 @@ async function builder(metadata, { output }) { exports: 'auto', }); } + + let declarationFile = `${templates.banner} + +import { Icon } from './types/Icon'; + +`; + + for (const m of modules) { + declarationFile += `export const ${m.name}: Icon;\n`; + } + + await fs.writeFile(path.join(output, 'index.d.ts'), declarationFile); } /** diff --git a/packages/icons-react/.gitignore b/packages/icons-react/.gitignore index f6d4e81c7c12..c933974ca356 100644 --- a/packages/icons-react/.gitignore +++ b/packages/icons-react/.gitignore @@ -1,2 +1,2 @@ -# TODO: remove in v11 -/next +# Generated declaration file +index.d.ts diff --git a/packages/icons-react/package.json b/packages/icons-react/package.json index 6eee0e5be6e1..ac24e17b9eb2 100644 --- a/packages/icons-react/package.json +++ b/packages/icons-react/package.json @@ -13,7 +13,9 @@ "bugs": "https://github.com/carbon-design-system/carbon/issues", "files": [ "es", - "lib" + "lib", + "index.d.ts", + "types" ], "keywords": [ "ibm", @@ -29,9 +31,10 @@ }, "scripts": { "build": "yarn clean && node tasks/build.js", - "clean": "rimraf es lib", + "clean": "rimraf es lib index.d.ts", "postinstall": "carbon-telemetry collect --install" }, + "types": "./index.d.ts", "peerDependencies": { "react": ">=16" }, diff --git a/packages/icons-react/tsconfig.json b/packages/icons-react/tsconfig.json new file mode 100644 index 000000000000..915179d9fe2c --- /dev/null +++ b/packages/icons-react/tsconfig.json @@ -0,0 +1,4 @@ +{ + "extends": "../../tsconfig.base.json", + "include": ["index.d.ts", "types"] +} diff --git a/packages/icons-react/types/Icon.d.ts b/packages/icons-react/types/Icon.d.ts new file mode 100644 index 000000000000..65601fa5a147 --- /dev/null +++ b/packages/icons-react/types/Icon.d.ts @@ -0,0 +1,41 @@ +/** + * Copyright IBM Corp. 2019, 2019 + * + * This source code is licensed under the Apache-2.0 license found in the + * LICENSE file in the root directory of this source tree. + */ + +import * as React from 'react'; + +type IconSize = 16 | 20 | 24 | 32 | '16' | '20' | '24' | '32' | number | string; + +// Inspired by the original types defined in DefinitelyTyped: +// https://github.com/DefinitelyTyped/DefinitelyTyped/blob/31fb0ded56cff23b7e6693bd673b00f41dc00bbe/types/carbon__icons-react/index.d.ts +interface IconProps + extends Omit< + React.SVGProps, + 'ref' | 'tabIndex' | 'aria-hidden' + > { + /** + * @default "currentColor" + */ + fill: string; + + /** + * Specify the size of the icon. This value can be one of the predetermined + * sizes for this icon (16, 20, 24, 32) or it can be a custom value that is + * used for the width and height of the element + * + * @default 16 + */ + size?: IconSize; + + /** + * @default "http://www.w3.org/2000/svg" + */ + xmlns?: string; +} + +export type Icon = React.ForwardRefExoticComponent< + IconProps & React.RefAttributes +>; diff --git a/tsconfig.base.json b/tsconfig.base.json new file mode 100644 index 000000000000..cefcd45b1f2a --- /dev/null +++ b/tsconfig.base.json @@ -0,0 +1,26 @@ +{ + "compilerOptions": { + "lib": ["es2015.iterable", "es2015.generator", "es5"], + "moduleResolution": "node", + + "declaration": true, + "declarationMap": true, + "sourceMap": true, + "composite": true, + "noEmitOnError": true, + + "strictNullChecks": true, + "noImplicitAny": true, + "noImplicitThis": true, + "strictPropertyInitialization": true, + "noUnusedLocals": true, + "noUnusedParameters": true, + + "alwaysStrict": true, + "preserveConstEnums": true, + + "jsx": "preserve", + + "types": [] + } +} diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 000000000000..97b189ca028b --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,9 @@ +{ + "files": [], + "include": [], + "references": [ + { + "path": "./packages/icons-react" + } + ] +} diff --git a/yarn.lock b/yarn.lock index fdd298ad1879..6182825f77e8 100644 --- a/yarn.lock +++ b/yarn.lock @@ -10796,6 +10796,7 @@ __metadata: react-dom: ^17.0.2 rimraf: ^3.0.0 stylelint: ^14.3.0 + typescript: ^4.7.2 languageName: unknown linkType: soft @@ -30908,23 +30909,23 @@ resolve@^2.0.0-next.3: languageName: node linkType: hard -"typescript@npm:^4.6.4": - version: 4.7.2 - resolution: "typescript@npm:4.7.2" +"typescript@npm:^4.6.4, typescript@npm:^4.7.2": + version: 4.8.2 + resolution: "typescript@npm:4.8.2" bin: tsc: bin/tsc tsserver: bin/tsserver - checksum: 5163585e6b56410f77d5483b698d9489bbee8902c99029eb70cf6d21525a186530ce19a00951af84eefd4a131cc51d0959f5118e25e70ab61f45ac4057dbd1ef + checksum: 7f5b81d0d558c9067f952c7af52ab7f19c2e70a916817929e4a5b256c93990bf3178eccb1ac8a850bc75df35f6781b6f4cb3370ce20d8b1ded92ed462348f628 languageName: node linkType: hard -"typescript@patch:typescript@^4.6.4#~builtin": - version: 4.7.2 - resolution: "typescript@patch:typescript@npm%3A4.7.2#~builtin::version=4.7.2&hash=7ad353" +"typescript@patch:typescript@^4.6.4#~builtin, typescript@patch:typescript@^4.7.2#~builtin": + version: 4.8.2 + resolution: "typescript@patch:typescript@npm%3A4.8.2#~builtin::version=4.8.2&hash=7ad353" bin: tsc: bin/tsc tsserver: bin/tsserver - checksum: 7e2b9a9f4a70fb7616f1b0d986977f8e34a74f046202fa7f24fdee79589598277810fa216b3776c20c0683a9235872c73be34fdb93f67f98c1efaca40999422f + checksum: 6f49363af8af2fe480da1d5fa68712644438785208b06690a3cbe5e7365fd652c3a0f1e587bc8684d78fb69de3dde4de185c0bad7bb4f3664ddfc813ce8caad6 languageName: node linkType: hard