Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit c0c33f4

Browse files
TypeScript usage - configuration & code adaptation (#25)
* Add and configure TypeScript for RN project * Add TypeScript types check to CI workflow The CI will now check the TypeScript code against any errors. All files containing JavaScript code has been renamed to indictate TypeScript (*.tsx). * Fix: tsc --pretty errors and type errors * Cover review remarks
1 parent 9aa8062 commit c0c33f4

File tree

11 files changed

+211
-69
lines changed

11 files changed

+211
-69
lines changed

‎.circleci/config.yml‎

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,9 @@ jobs:
4343
- run:
4444
name: "Verify the standards and code quality"
4545
command: npx eslint ./src/**
46+
- run:
47+
name: "Check the TypeScript code quality"
48+
command: yarn tsc --pretty
4649

4750
# Application build
4851
build-Application-Configuration-Platform:

‎package.json‎

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,12 +21,17 @@
2121
"@babel/runtime": "^7.8.4",
2222
"@callstack/eslint-config": "^11.0.0",
2323
"@react-native-community/eslint-config": "^1.1.0",
24+
"@types/jest": "^26.0.23",
25+
"@types/react": "^17.0.13",
26+
"@types/react-native": "^0.64.10",
27+
"@types/react-test-renderer": "^17.0.1",
2428
"babel-jest": "^25.1.0",
2529
"eslint": "^7.29.0",
2630
"jest": "^25.1.0",
2731
"metro-react-native-babel-preset": "^0.59.0",
2832
"prettier": "2.3.2",
29-
"react-test-renderer": "16.13.1"
33+
"react-test-renderer": "16.13.1",
34+
"typescript": "^4.3.5"
3035
},
3136
"husky": {
3237
"hooks": {

‎src/CreateNotePanel.js‎ renamed to ‎src/CreateNotePanel.tsx‎

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,20 +14,27 @@ import {
1414
} from 'react-native';
1515
import Colors from './Resources/Colors';
1616

17-
class CreateNotePanel extends React.Component {
18-
constructor(props) {
17+
interface Props {}
18+
19+
interface State {
20+
title: string;
21+
message: string;
22+
}
23+
24+
class CreateNotePanel extends React.Component<Props, State> {
25+
constructor(props: Props) {
1926
super(props);
2027
this.state = {
2128
title: '',
2229
message: '',
2330
};
2431
}
2532

26-
titleOnChange = (text) => {
33+
titleOnChange = (text: string) => {
2734
this.setState({title: text});
2835
};
2936

30-
messageOnChange = (text) => {
37+
messageOnChange = (text: string) => {
3138
this.setState({message: text});
3239
};
3340

‎src/NoteWidgetDetailsPanel.js‎ renamed to ‎src/NoteWidgetDetailsPanel.tsx‎

Lines changed: 23 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,17 @@ import {
1414
} from 'react-native';
1515
import Colors from './Resources/Colors';
1616

17-
class NoteWidgetDetailsPanel extends React.Component {
18-
constructor(props) {
17+
interface Props {}
18+
19+
interface State {
20+
id: number;
21+
title: string;
22+
message: string;
23+
isEditing: boolean;
24+
}
25+
26+
class NoteWidgetDetailsPanel extends React.Component<Props, State> {
27+
constructor(props: Props) {
1928
super(props);
2029
this.state = {
2130
id: 0,
@@ -27,41 +36,44 @@ class NoteWidgetDetailsPanel extends React.Component {
2736

2837
async componentDidMount() {
2938
await NativeModules.NoteWidgetClickHandler.openedNoteID()
30-
.then((result) => {
39+
.then((result: number) => {
3140
this.setState({id: result});
3241
this.getNoteTitle();
3342
this.getNoteMessage();
3443
return 0;
3544
})
36-
.catch((error) => {
37-
Alert.alert('ERROR!', `Could not find the opened note\n${error}`);
45+
.catch((error: Error) => {
46+
Alert.alert(
47+
'ERROR!',
48+
`Could not find the opened note\n${error.message}`,
49+
);
3850
});
3951
}
4052

41-
titleOnChange = (text) => {
53+
titleOnChange = (text: string) => {
4254
this.setState({title: text});
4355
};
4456

45-
messageOnChange = (text) => {
57+
messageOnChange = (text: string) => {
4658
this.setState({message: text});
4759
};
4860

4961
getNoteTitle = async () => {
5062
await NativeModules.Database.getNoteTitle(this.state.id)
51-
.then((result) => {
63+
.then((result: string) => {
5264
this.setState({title: result});
5365
return 0;
5466
})
55-
.catch((error) => Alert.alert('ERROR!', `${error}`));
67+
.catch((error: Error) => Alert.alert('ERROR!', `${error.message}`));
5668
};
5769

5870
getNoteMessage = async () => {
5971
await NativeModules.Database.getNotePost(this.state.id)
60-
.then((result) => {
72+
.then((result: string) => {
6173
this.setState({message: result});
6274
return 0;
6375
})
64-
.catch((error) => Alert.alert('ERROR!', `${error}`));
76+
.catch((error: Error) => Alert.alert('ERROR!', `${error.message}`));
6577
};
6678

6779
cancelButtonPressed = () => {

‎src/NotesMainPanel.js‎ renamed to ‎src/NotesMainPanel.tsx‎

Lines changed: 36 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -16,30 +16,37 @@ import {
1616
import NoteWidget from './Widgets/NoteWidget';
1717
import Colors from './Resources/Colors';
1818

19-
const window = Dimensions.get('window');
20-
const screen = Dimensions.get('screen');
21-
2219
const noteWidgetWidth = 300;
2320

24-
class NotesMainPanel extends React.Component {
25-
constructor(props) {
21+
function calculateColumnWidth() {
22+
return Math.floor(Dimensions.get('window').width / noteWidgetWidth);
23+
}
24+
25+
interface Props {}
26+
27+
interface INote {
28+
key: number;
29+
title: string;
30+
shortMessage: string;
31+
}
32+
33+
interface State {
34+
notes: Array<INote>;
35+
columns: number;
36+
}
37+
38+
class NotesMainPanel extends React.Component<Props, State> {
39+
constructor(props: Props) {
2640
super(props);
2741
this.state = {
2842
notes: [],
29-
dimensions: {window, screen},
30-
columns: this.calculateColumnWidth(window),
31-
isMounted: false,
43+
columns: calculateColumnWidth(),
3244
};
3345
}
3446

35-
calculateColumnWidth = () => {
36-
return Math.floor(Dimensions.get('window').width / noteWidgetWidth);
37-
};
38-
39-
onChange = ({window, screen}) => {
47+
onChange = () => {
4048
this.setState({
41-
dimensions: {window, screen},
42-
columns: this.calculateColumnWidth(),
49+
columns: calculateColumnWidth(),
4350
});
4451
};
4552

@@ -52,25 +59,16 @@ class NotesMainPanel extends React.Component {
5259
Dimensions.removeEventListener('change', this.onChange);
5360
}
5461

55-
createNotesKeys = async (notesIDs) => {
62+
createNotesKeys = async (notesIDs: Array<INote>) => {
5663
this.setState({notes: notesIDs});
5764
};
5865

5966
getDataFromDatabase = async () => {
6067
await NativeModules.Database.getAllNotesIDs()
61-
.then((result) => this.createNotesKeys(result))
62-
.catch((error) => Alert.alert('ERROR!', `Result: ${error}`));
63-
};
64-
65-
renderNote = (notes) => {
66-
return (
67-
<NoteWidget
68-
width={noteWidgetWidth}
69-
ID={notes.item.key}
70-
title={notes.item.title}
71-
shortMessage={notes.item.shortMessage}
72-
/>
73-
);
68+
.then((result: Array<INote>) => this.createNotesKeys(result))
69+
.catch((error: Error) =>
70+
Alert.alert('ERROR!', `Result: ${error.message}`),
71+
);
7472
};
7573

7674
renderWelcomePage = () => {
@@ -89,11 +87,18 @@ class NotesMainPanel extends React.Component {
8987
renderNotesPage = () => {
9088
return (
9189
<View style={styles.mainContainer}>
92-
<FlatList
90+
<FlatList<INote>
9391
key={this.state.columns}
9492
numColumns={this.state.columns}
9593
data={this.state.notes}
96-
renderItem={this.renderNote}
94+
renderItem={({item}) => (
95+
<NoteWidget
96+
width={noteWidgetWidth}
97+
id={item.key}
98+
title={item.title}
99+
shortMessage={item.shortMessage}
100+
/>
101+
)}
97102
/>
98103
</View>
99104
);
File renamed without changes.

‎src/ToDoListPanel.js‎ renamed to ‎src/ToDoListPanel.tsx‎

Lines changed: 28 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -15,23 +15,38 @@ import DateTimePicker from '@react-native-community/datetimepicker';
1515
import TaskWidget from './Widgets/TaskWidget';
1616
import Colors from './Resources/Colors';
1717

18-
class ToDoListPanel extends React.Component {
19-
constructor(props) {
18+
interface Props {}
19+
20+
interface Task {
21+
key: number;
22+
message: string;
23+
dueDate: Date | undefined;
24+
}
25+
26+
interface State {
27+
tasks: Array<Task>;
28+
number: number;
29+
message: string;
30+
selectedDate: Date | undefined;
31+
}
32+
33+
class ToDoListPanel extends React.Component<Props, State> {
34+
constructor(props: Props) {
2035
super(props);
2136
this.state = {
2237
tasks: [],
2338
number: 0,
2439
message: '',
25-
selectedDate: new Date(0),
40+
selectedDate: new Date(),
2641
};
2742
}
2843

29-
onChange = (event, selectedDate) => {
44+
onChange = (event: Event, selectedDate?: Date) => {
3045
const currentDate = selectedDate;
3146
this.setState({selectedDate: currentDate});
3247
};
3348

34-
messageOnChange = (text) => {
49+
messageOnChange = (text: string) => {
3550
this.setState({message: text});
3651
};
3752

@@ -52,24 +67,20 @@ class ToDoListPanel extends React.Component {
5267
});
5368
};
5469

55-
renderTask = (tasks) => {
56-
return (
57-
<TaskWidget
58-
ID={tasks.item.key}
59-
message={tasks.item.message}
60-
dueDate={tasks.item.dueDate}
61-
/>
62-
);
63-
};
64-
6570
render() {
6671
return (
6772
<View style={styles.mainPanel}>
6873
<View style={styles.flatListPanel}>
6974
<FlatList
7075
numColumns={1}
7176
data={this.state.tasks}
72-
renderItem={this.renderTask}
77+
renderItem={({item}) => (
78+
<TaskWidget
79+
id={item.key}
80+
message={item.message}
81+
dueDate={item.dueDate}
82+
/>
83+
)}
7384
/>
7485
</View>
7586

@@ -83,7 +94,7 @@ class ToDoListPanel extends React.Component {
8394
<View style={styles.createButtons}>
8495
<Button title={'Add'} onPress={this.addButtonPressed} />
8596
<DateTimePicker
86-
value={this.state.selectedDate}
97+
value={this.state.selectedDate||newDate()}
8798
is24Hour={true}
8899
display="default"
89100
onChange={this.onChange}

‎src/Widgets/NoteWidget.js‎ renamed to ‎src/Widgets/NoteWidget.tsx‎

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,11 +13,18 @@ import {
1313
} from 'react-native';
1414
import Colors from '../Resources/Colors';
1515

16-
export default function NoteWidget(props) {
17-
const {width, ID, title, shortMessage} = props;
16+
interface Props {
17+
width: number;
18+
id: number;
19+
title: string;
20+
shortMessage: string;
21+
}
22+
23+
export default function NoteWidget(props: Props) {
24+
const {width, id, title, shortMessage} = props;
1825

1926
const enterNote = () => {
20-
NativeModules.NoteWidgetClickHandler.openWidget(ID);
27+
NativeModules.NoteWidgetClickHandler.openWidget(id);
2128
};
2229

2330
return (

‎src/Widgets/TaskWidget.js‎ renamed to ‎src/Widgets/TaskWidget.tsx‎

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,13 @@ import {AppRegistry, StyleSheet, Text, View} from 'react-native';
88
import CheckBox from '@react-native-community/checkbox';
99
import Colors from '../Resources/Colors';
1010

11-
export default function TaskWidget(props) {
11+
interface Props {
12+
id: number;
13+
message: string;
14+
dueDate: Date | undefined;
15+
}
16+
17+
export default function TaskWidget(props: Props) {
1218
const {message, dueDate} = props;
1319

1420
const [isDone, setIsDone] = useState(false);

‎tsconfig.json‎

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
{
2+
"compilerOptions": {
3+
"allowJs": true,
4+
"allowSyntheticDefaultImports": true,
5+
"esModuleInterop": true,
6+
"isolatedModules": true,
7+
"jsx": "react",
8+
"lib": ["es6"],
9+
"moduleResolution": "node",
10+
"noEmit": true,
11+
"strict": true,
12+
"target": "esnext"
13+
},
14+
"exclude": [
15+
"node_modules",
16+
"babel.config.js",
17+
"metro.config.js",
18+
"jest.config.js"
19+
]
20+
}

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /