Skip to content

Commit cf1360c

Browse files
ci: lint TypeScript output script
1 parent 973ee86 commit cf1360c

File tree

2 files changed

+119
-5
lines changed

2 files changed

+119
-5
lines changed

.circleci/config.yml

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -34,19 +34,19 @@ jobs:
3434
yarn install --frozen-lockfile
3535
- save_cache:
3636
key: dependencies-{{ checksum "package.json" }}
37-
paths:
37+
paths:
3838
- node_modules
3939
- save_cache:
4040
key: dependencies-docs-{{ checksum "docs/package.json" }}
41-
paths:
41+
paths:
4242
- docs/node_modules
4343
- save_cache:
4444
key: dependencies-example-{{ checksum "example/package.json" }}
45-
paths:
45+
paths:
4646
- example/node_modules
4747
- persist_to_workspace:
4848
root: .
49-
paths:
49+
paths:
5050
- .
5151
lint:
5252
executor: default
@@ -65,6 +65,7 @@ jobs:
6565
name: Typecheck files
6666
command: |
6767
yarn typescript
68+
node ./scripts/typescript-output-lint
6869
6970
unit-tests:
7071
executor: default
@@ -83,7 +84,7 @@ jobs:
8384
path: coverage
8485
destination: coverage
8586
- save_cache:
86-
paths:
87+
paths:
8788
- ./cache/jest
8889
key: jest-cache-{{ .Branch }}
8990

scripts/typescript-output-lint.js

Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
const { promises: fs } = require('fs');
2+
const path = require('path');
3+
4+
const root = path.resolve(__dirname, '..');
5+
const output = path.join(root, 'lib', 'typescript');
6+
7+
/**
8+
* List of React Native props not used by React Native Paper.
9+
* Feel free to delete props from this list when
10+
* React Native Paper has defined/uses one with the same name.
11+
* This script was originally created to detect if TypeScript
12+
* has exported a large union of props from ViewProps.
13+
* More info: https://github.com/callstack/react-native-paper/pull/3603
14+
*/
15+
const unusedViewProps = [
16+
'nativeID',
17+
'accessibilityActions',
18+
'accessibilityRole',
19+
'accessibilityValue',
20+
'onAccessibilityAction',
21+
'accessibilityLabelledBy',
22+
'accessibilityLiveRegion',
23+
'accessibilityLanguage',
24+
'accessibilityViewIsModal',
25+
'onAccessibilityEscape',
26+
'onAccessibilityTap',
27+
'onMagicTap',
28+
'accessibilityIgnoresInvertColors',
29+
'hitSlop',
30+
'removeClippedSubviews',
31+
'collapsable',
32+
'needsOffscreenAlphaCompositing',
33+
'renderToHardwareTextureAndroid',
34+
'shouldRasterizeIOS',
35+
'isTVSelectable',
36+
'hasTVPreferredFocus',
37+
'tvParallaxProperties',
38+
'tvParallaxShiftDistanceX',
39+
'tvParallaxShiftDistanceY',
40+
'tvParallaxTiltAngle',
41+
'tvParallaxMagnification',
42+
'onStartShouldSetResponder',
43+
'onMoveShouldSetResponder',
44+
'onResponderEnd',
45+
'onResponderGrant',
46+
'onResponderReject',
47+
'onResponderMove',
48+
'onResponderRelease',
49+
'onResponderStart',
50+
'onResponderTerminationRequest',
51+
'onResponderTerminate',
52+
'onStartShouldSetResponderCapture',
53+
'onMoveShouldSetResponderCapture',
54+
'onTouchStart',
55+
'onTouchMove',
56+
'onTouchEnd',
57+
'onTouchCancel',
58+
'onTouchEndCapture',
59+
'onPointerEnter',
60+
'onPointerEnterCapture',
61+
'onPointerLeave',
62+
'onPointerLeaveCapture',
63+
'onPointerMove',
64+
'onPointerMoveCapture',
65+
'onPointerCancel',
66+
'onPointerCancelCapture',
67+
'onPointerDown',
68+
'onPointerDownCapture',
69+
'onPointerUp',
70+
'onPointerUpCapture',
71+
'onHoverIn',
72+
'onHoverOut',
73+
'cancelable',
74+
'delayHoverIn',
75+
'delayHoverOut',
76+
'pressRetentionOffset',
77+
'android_disableSound',
78+
'android_ripple',
79+
'testOnly_pressed',
80+
'unstable_pressDelay',
81+
];
82+
83+
async function* getFiles(directory) {
84+
const entries = await fs.readdir(directory, { withFileTypes: true });
85+
for (const entry of entries) {
86+
const res = path.resolve(directory, entry.name);
87+
if (entry.isDirectory()) {
88+
yield* getFiles(res);
89+
} else {
90+
yield res;
91+
}
92+
}
93+
}
94+
95+
async function main() {
96+
for await (const file of getFiles(output)) {
97+
const content = await fs.readFile(file);
98+
for (const prop of unusedViewProps) {
99+
if (content.includes(prop)) {
100+
throw new Error(
101+
`Found text '${prop}' in '${file}'. Please use the wrapped 'forwardRef' in 'src/utils/forwardRef.ts', export some return types, or modify 'scripts/typescript-output-lint.js'`
102+
);
103+
}
104+
}
105+
}
106+
107+
console.log('✅ No React Native props mentioned in TypeScript files');
108+
}
109+
110+
main().catch((reason) => {
111+
console.error(reason);
112+
process.exit(1);
113+
});

0 commit comments

Comments
 (0)