Skip to content

Commit 02d9abf

Browse files
li-kaiZhangYiJiang
authored andcommitted
Migrate www to typescript (#1537)
* Rename all js, jsx to ts, tsx * Add typescript configuration * Add naive flow -> typescript convertor * Add configuration to fix typescript code * Convert flow to typescript * Add more typings * Fix double React bug * Fix some simple typings * Fix ExternalLink typing * Fix ScrollToTop and React util * Fix CORS notification * Fix TimeslotTable * Fix SearchBox * Fix config * Fix venues * Fix CORS * Fix StaticPage * Fix query-string type version * Fix ModulePageContainer test * Fix some more stuff * Fix custom module form * Fix AddModule * Fix TodayContainer * Fix RefreshPrompt * Fix VenueContainer * Fixing things * Revert e2e test code to JS * Update packages * Fix stuff * Delete all Flow typedefs * Fix even more stuff * Update some configs * Fix up eslint * Fixing stuff * Fixing more code * Update stuff * Maybe fix CI * Fix stuff * Fix more stuff * Add simple fixes * Add more simple fixes * Fix footer * Fix image types and global window extension * Fix all reducers except undoHistory * Fix global search test * Add NUSModerator libdef * Fix ExamCalendar * Fix up Redux actions * Fix bootstrapping (except config store * Fix up test-utils * Fix timetable export typing * Fix today views * Update planner types * Fix layout components * Fix simple components * Update global and installed typings Downgrade Jest typings to avoid bug with mockResolve/Reject * Update module-info and ButtonGroup component * Fix weekText test * Fix typing for module pages Still need to add a libdef for react-scrollspy * Fix component types TODO: Figure out how to type dynamic imports * Fix selectors * Fix planner reducer * Fix Contribute container * Improve venue typing TODO: Fix react-leaflet types, timetable types * Fix error components * Fix middleware typing * Fix settings views * Fix routes typing * Fix venueLocation JSON typing * Fix CorsNotification test * Fix storage strict errors * Improve util types * Add React Kawaii libdef * Fix react-feather import * Improve timetable typing * Skip checking .d.ts files * Fix more types * Fix filter views * Mark Disqus page as any * Add json2mq types and fix CSs util * Fix share timetable * Fix BusStops and split ArrivalTimes * Add react-scrollspy libdef * Fix colors util * Fix module page views * Add react leaflet types * Fix ImproveVenueForm * Incomplete fixes for planner and filters * Fix modulePage route * Hack board.ts * Fix request middleware test typing * Fix Sentry typing * Add more leaflet typings * Fix TetrisGame * Fix reducers test * Add no-scroll libdef * Fix BusStops test * Fix api types * Add typing for weather API responses * Fix moduleBank and requests tests * Fix minor bugs in planner and modtris typing * Fix history debouncer test mock typing * Fix storage types * Ignore some minor TS errors * Realign Timetable types * Improve HOC typing * Fix iCal tests * Improve timetable test types * Fix up more types * Run eslint autofix * Fix undoHistory type * Fix lint errors * Fix SVG component typing * Fix filter groups * Fix test configs * Update snapshots * Fix hoc typing See: microsoft/TypeScript#28938 (comment) * Fix jest tests * Remove flow typings * Fix timetable-export webpack config * Clean up tsconfig * Improve babel config * Fix lint errors and improve typing * Remove and simplify lint ignores * Clean up more types * Directly import react-feather icons * Remove migration script * Remove final traces of flow * Clean up Babel configs * Minor fixes and comments * Remove unused packages * Update README and add tsc to CI
1 parent 3c8b36e commit 02d9abf

File tree

433 files changed

+5450
-28961
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

433 files changed

+5450
-28961
lines changed

.circleci/config.yml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -108,12 +108,12 @@ jobs:
108108
NODE_ENV: test
109109
command: yarn
110110
- save_cache: *save_node_deps
111-
- run:
112-
name: Type check code
113-
command: yarn flow
114111
- run:
115112
name: Lint code
116113
command: yarn lint:code --format junit -o reports/junit/js-lint-results.xml
114+
- run:
115+
name: Typecheck Code
116+
command: yarn typecheck
117117
- run:
118118
name: Test code
119119
environment:

www/.eslintrc.js

Lines changed: 42 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,34 +1,30 @@
11
const warnInDevelopment = process.env.NODE_ENV === 'production' ? 'error' : 'warn';
22

33
module.exports = {
4-
parser: 'babel-eslint',
4+
parser: '@typescript-eslint/parser',
5+
6+
parserOptions: {
7+
project: './tsconfig.json',
8+
},
9+
510
root: true,
6-
extends: [
7-
'airbnb',
8-
'plugin:flowtype/recommended',
9-
'prettier',
10-
'prettier/flowtype',
11-
'prettier/react',
12-
],
11+
extends: ['airbnb', 'prettier', 'prettier/react'],
1312
env: {
1413
browser: true,
1514
},
16-
plugins: ['flowtype', 'prettier', 'import', 'jsx-a11y', 'react'],
15+
plugins: ['@typescript-eslint', 'prettier', 'import', 'jsx-a11y', 'react'],
16+
1717
settings: {
1818
'import/resolver': {
1919
webpack: {
2020
config: 'webpack/webpack.config.common.js',
2121
},
2222
},
23-
},
24-
overrides: [
25-
{
26-
files: ['**/*.test.{js,jsx}', '**/__mocks__/**/*.{js,jsx}'],
27-
env: {
28-
jest: true,
29-
},
23+
'import/parsers': {
24+
'@typescript-eslint/parser': ['.ts', '.tsx'],
3025
},
31-
],
26+
},
27+
3228
rules: {
3329
'prettier/prettier': warnInDevelopment,
3430

@@ -39,27 +35,40 @@ module.exports = {
3935
'no-alert': 'off',
4036
'prefer-destructuring': 'off',
4137

38+
// TODO: Should fix this - we don't want to accidentally create unresolvable dep chains
39+
'import/no-cycle': 'off',
40+
4241
'import/extensions': [
4342
warnInDevelopment,
4443
'always',
4544
{
4645
js: 'never',
4746
jsx: 'never',
47+
ts: 'never',
48+
tsx: 'never',
4849
},
4950
],
51+
52+
// Allow properties that are logically grouped together to be written
53+
// without line breaks
54+
'lines-between-class-members': 'off',
55+
5056
// Enable i++ in for loops
5157
'no-plusplus': ['error', { allowForLoopAfterthoughts: true }],
5258
'no-bitwise': 'off',
5359

5460
'react/no-array-index-key': 'off',
61+
5562
// SEE: https://github.com/yannickcr/eslint-plugin-react/issues
5663
'react/no-unused-prop-types': 'off',
64+
5765
// Enables typing to be placed above lifecycle
5866
'react/sort-comp': [
5967
warnInDevelopment,
6068
{
6169
order: [
6270
'type-annotations',
71+
'instance-variables',
6372
'static-methods',
6473
'lifecycle',
6574
'/^on.+$/',
@@ -68,10 +77,20 @@ module.exports = {
6877
],
6978
},
7079
],
80+
7181
'react/require-default-props': 'off',
82+
'react/jsx-filename-extension': ['error', { extensions: ['.tsx', '.jsx'] }],
7283
'react/default-props-match-prop-types': ['error', { allowRequiredDefaults: true }],
84+
85+
// Too verbose, creates too many variables
86+
'react/destructuring-assignment': 'off',
87+
88+
// TODO: Fix this
89+
'react/no-access-state-in-setstate': 'warn',
90+
7391
// TODO: Replace divs with buttons, but remove all button styling.
7492
'jsx-a11y/no-static-element-interactions': 'off',
93+
7594
// The default option requires BOTH id and nesting, which is excessive,
7695
// especially with checkboxes and radiobuttons. This changes it to EITHER
7796
'jsx-a11y/label-has-for': [
@@ -82,6 +101,7 @@ module.exports = {
82101
},
83102
},
84103
],
104+
85105
// Link fails this rule as it has no "href" prop.
86106
'jsx-a11y/anchor-is-valid': [
87107
'error',
@@ -90,11 +110,16 @@ module.exports = {
90110
specialLink: ['to'],
91111
},
92112
],
113+
114+
// Rule appear to be buggy when used with @typescript-eslint/parser
115+
'jsx-a11y/label-has-associated-control': 'off',
116+
93117
// For use with immer
94118
'no-param-reassign': [
95119
'error',
96120
{ props: true, ignorePropertyModificationsFor: ['draft', 'draftState'] },
97121
],
122+
98123
// Let git handle the linebreaks instead.
99124
'linebreak-style': 'off',
100125
},

www/.flowconfig

Lines changed: 0 additions & 24 deletions
This file was deleted.

www/README.md

Lines changed: 24 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -46,10 +46,10 @@ To run the development build, simply run:
4646
$ yarn start
4747
```
4848

49-
This will start webpack dev server, which will automatically rebuild and reload any code and components that you have changed. If your editor or IDE has built in support for Flow/ESLint/StyleLint, you can disable them to speed up the build process.
49+
This will start Webpack dev server, which will automatically rebuild and reload any code and components that you have changed. If your editor or IDE has built in support for ESLint/StyleLint, you can disable them to speed up the build process.
5050

5151
```sh
52-
$ DISABLE_ESLINT=1 DISABLE_FLOW=1 DISABLE_STYLELINT=1 yarn start
52+
$ DISABLE_ESLINT=1 DISABLE_STYLELINT=1 yarn start
5353
```
5454

5555
We recommend the following development tools to help speed up your work
@@ -168,11 +168,15 @@ type Props = {
168168
}
169169

170170
type State = {
171-
data: ?MyData,
171+
data: MyData | null,
172172
error?: any,
173173
}
174174

175-
class MyComponent extends Component<Props> {
175+
class MyComponent extends React.Component<Props, State> {
176+
state: State = {
177+
data: null,
178+
};
179+
176180
componentDidMount() {
177181
this.props.fetchData()
178182
.then(data => this.setState({ data }))
@@ -186,7 +190,7 @@ class MyComponent extends Component<Props> {
186190
return <ErrorPage />;
187191
}
188192

189-
if (!data) {
193+
if (data == null) {
190194
return <LoadingSpinner />;
191195
}
192196

@@ -207,7 +211,7 @@ This is the [cache-then-network strategy described in the Offline Cookbook][offl
207211
208212
**Reducer example**
209213
210-
```js
214+
```ts
211215
import { SUCCESS } from 'types/reducers';
212216
import { FETCH_DATA } from 'actions/example';
213217

@@ -225,17 +229,17 @@ export function exampleBank(state: ExampleBank, action: FSA): ExampleBank {
225229
226230
**Component example**
227231
228-
```js
232+
```ts
229233
type Props = {
230-
myData: ?MyData,
234+
myData: MyData | null,
231235
fetchData: () => Promise<MyData>,
232236
}
233237

234238
type State = {
235239
error?: any,
236240
}
237241

238-
class MyComponent extends Component<Props> {
242+
class MyComponent extends React.Component<Props, State> {
239243
componentDidMount() {
240244
this.props.fetchData()
241245
.catch(error => this.setState({ error });
@@ -250,7 +254,7 @@ class MyComponent extends Component<Props> {
250254
return <ErrorPage />;
251255
}
252256

253-
if (!data) {
257+
if (data == null) {
254258
return <LoadingSpinner />;
255259
}
256260

@@ -271,21 +275,16 @@ If you need to access the status of a request from outside the component which i
271275
272276
NUSMods tries to be as lean as possible. Adding external dependencies should be done with care to avoid bloating our bundle. Use [Bundlephobia][bundlephobia] to ensure the new dependency is reasonably sized, or if the dependency is limited to one specific page/component, use code splitting to ensure the main bundle's size is not affected.
273277
274-
#### Flow libdef
278+
#### TypeScript libdef
275279
276-
When adding a JavaScript package, Flow requires a library definition, or libdef. To try to install one from the [community repository][flow-typed], use the `flow-typed` command. If a community libdef is not available, the same command can also be used to create a stub libdef which you can use immediately in a pinch, or edit to fill in the correct definitions.
280+
When adding a JavaScript package, Flow requires a library definition, or libdef. To try to install one from the [community repository][definitely-typed], install `@types/<package name>`. Make sure the installed libdef's version matches that of the package.
277281
278-
```sh
279-
# Use ./node_modules/.bin/flow-typed if you don't want to use npx
280-
npx flow-typed install [email protected]
282+
If a community libdef is not available, you can try writing your own and placing it in `js/types/vendor`.
281283
282-
# Use create-stub for packages without community libdef
283-
npx flow-typed create-stub my-dep
284-
```
285284
286285
### Testing and Linting
287286
288-
We use [Jest][jest] with [Enzyme][enzyme] to test our code and React components, [Flow][flow] for typechecking, [Stylelint][stylelint] and [ESLint][eslint] using [Airbnb config][eslint-airbnb] and [Prettier][prettier] for linting and formatting.
287+
We use [Jest][jest] with [Enzyme][enzyme] to test our code and React components, [TypeScript][ts] for typechecking, [Stylelint][stylelint] and [ESLint][eslint] using [Airbnb config][eslint-airbnb] and [Prettier][prettier] for linting and formatting.
289288
290289
```sh
291290
# Run all tests once with code coverage
@@ -305,8 +304,8 @@ $ yarn lint:code
305304
# p.s. Use yarn lint:styles --fix with care (it's experimental),
306305
# remember to reset changes for themes.scss.
307306
308-
# Run Flow type checking
309-
$ yarn flow
307+
# Run TypeScript type checking
308+
$ yarn typecheck
310309
```
311310
312311
#### End to End testing
@@ -366,7 +365,8 @@ $ yarn promote-staging # Promote ./dist to production
366365
│   │   ├── test-utils - Utilities for testing - this directory is not counted
367366
│   │   │ for test coverage
368367
│   │   ├── timetable-export - Entry point for timetable only build for exports
369-
│   │   ├── types - Flow type definitions
368+
│   │   ├── types - Type definitions
369+
│   │   └── vendor - Types for third party libaries
370370
│   │   ├── utils - Utility functions and classes
371371
│   │   └── views
372372
│   │   ├── components - Reusable components
@@ -411,7 +411,7 @@ Components should keep their styles and tests in the same directory with the sam
411411
[bootstrap]: https://getbootstrap.com/
412412
[jest]: https://facebook.github.io/jest/
413413
[enzyme]: http://airbnb.io/enzyme/
414-
[flow]: https://flow.org/
414+
[ts]: https://www.typescriptlang.org/
415415
[eslint]: https://eslint.org/
416416
[svgr]: https://github.com/smooth-code/svgr
417417
[eslint-airbnb]: https://www.npmjs.com/package/eslint-config-airbnb
@@ -421,5 +421,5 @@ Components should keep their styles and tests in the same directory with the sam
421421
[css-modules]: https://github.com/css-modules/css-modules
422422
[offline-cookbook]: https://developers.google.com/web/fundamentals/instant-and-offline/offline-cookbook/#cache-then-network
423423
[axios-config]: https://github.com/axios/axios#request-config
424-
[flow-typed]: https://github.com/flow-typed/flow-typed
424+
[definitely-typed]: https://github.com/DefinitelyTyped/DefinitelyTyped/
425425
[bundlephobia]: https://bundlephobia.com/

www/babel.config.js

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ module.exports = (api) => {
66
const IS_TEST = api.env('test');
77

88
const presets = [
9+
'@babel/preset-typescript',
910
[
1011
'@babel/preset-env',
1112
{
@@ -18,7 +19,6 @@ module.exports = (api) => {
1819
},
1920
],
2021
['@babel/preset-react', { development: !IS_PROD }],
21-
'@babel/preset-flow',
2222
];
2323

2424
const plugins = [
@@ -33,9 +33,11 @@ module.exports = (api) => {
3333
if (IS_DEV || IS_PROD) {
3434
plugins.push(['@babel/plugin-proposal-object-rest-spread', { useBuiltIns: true }]);
3535
}
36+
3637
if (IS_DEV) {
3738
plugins.push('react-hot-loader/babel');
3839
}
40+
3941
if (IS_PROD) {
4042
// React Optimize plugins
4143
plugins.push(
@@ -45,6 +47,7 @@ module.exports = (api) => {
4547
'babel-plugin-transform-react-class-to-function',
4648
);
4749
}
50+
4851
if (IS_TEST) {
4952
plugins.push('babel-plugin-dynamic-import-node');
5053
}

www/flow-typed/npm/@sentry/browser_vx.x.x.js

Lines changed: 0 additions & 18 deletions
This file was deleted.

0 commit comments

Comments
 (0)