Skip to content

Commit 33a16f9

Browse files
NickGerlemanfacebook-github-bot
authored andcommitted
Enforce compatibility with exactOptionalPropertyTypes (#36345)
Summary: Pull Request resolved: #36345 `exactOptionalPropertyTypes` is a TypeScript 4.4+ option set by users which changes behavior of optional properties, to disable accepting explicit `undefined`. This is not enabled when using `--strict`, and is stricter than Flow, leading to most of the typings having an `| undefined` unique to TypeScript (added with DefinitelyTyped/DefinitelyTyped@694c663). We have not always followed this (I have myself previously assumed the two are equivalent). We can enforce that the convention is followed with a plugin `eslint-plugin-redundant-undefined`. This forces us to declare that every optional property accepts an explicit undefined (which Flow would allow). Alternatively, if we do not want to support this, we can enable the existing dtslint rule `no-redundant-undefined`. Changelog: [General][Fixed] - Enforce compatibility with `exactOptionalPropertyTypes` Differential Revision: D43700862 fbshipit-source-id: 20dcbdf02dda4c2ab5c0d61b4d3bee16475b7b44
1 parent 71157f6 commit 33a16f9

File tree

27 files changed

+140
-68
lines changed

27 files changed

+140
-68
lines changed

.eslintrc.js

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,5 +91,15 @@ module.exports = {
9191
'react/self-closing-comp': 'off',
9292
},
9393
},
94+
{
95+
files: ['**/*.d.ts'],
96+
plugins: ['redundant-undefined'],
97+
rules: {
98+
'redundant-undefined/redundant-undefined': [
99+
'error',
100+
{followExactOptionalPropertyTypes: true},
101+
],
102+
},
103+
},
94104
],
95105
};

Libraries/Alert/Alert.d.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,14 +13,14 @@
1313
export interface AlertButton {
1414
text?: string | undefined;
1515
onPress?: ((value?: string) => void) | undefined;
16-
isPreferred?: boolean;
16+
isPreferred?: boolean | undefined;
1717
style?: 'default' | 'cancel' | 'destructive' | undefined;
1818
}
1919

2020
interface AlertOptions {
2121
/** @platform android */
2222
cancelable?: boolean | undefined;
23-
userInterfaceStyle?: 'unspecified' | 'light' | 'dark';
23+
userInterfaceStyle?: 'unspecified' | 'light' | 'dark' | undefined;
2424
/** @platform android */
2525
onDismiss?: (() => void) | undefined;
2626
}

Libraries/Animated/Animated.d.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -579,7 +579,7 @@ export namespace Animated {
579579
extends React.FC<AnimatedProps<React.ComponentPropsWithRef<T>>> {}
580580

581581
export type AnimatedComponentOptions = {
582-
collapsable?: boolean;
582+
collapsable?: boolean | undefined;
583583
};
584584

585585
/**

Libraries/Components/AccessibilityInfo/AccessibilityInfo.d.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -137,7 +137,7 @@ export interface AccessibilityInfoStatic {
137137
*/
138138
announceForAccessibilityWithOptions(
139139
announcement: string,
140-
options: {queue?: boolean},
140+
options: {queue?: boolean | undefined},
141141
): void;
142142

143143
/**

Libraries/Components/Pressable/Pressable.d.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -158,7 +158,7 @@ export interface PressableProps
158158
/**
159159
* Duration (in milliseconds) to wait after press down before calling onPressIn.
160160
*/
161-
unstable_pressDelay?: number;
161+
unstable_pressDelay?: number | undefined;
162162
}
163163

164164
// TODO use React.AbstractComponent when available

Libraries/Components/ScrollView/ScrollView.d.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -730,7 +730,7 @@ export interface ScrollViewProps
730730
/**
731731
* When true, Sticky header is hidden when scrolling down, and dock at the top when scrolling up.
732732
*/
733-
stickyHeaderHiddenOnScroll?: boolean;
733+
stickyHeaderHiddenOnScroll?: boolean | undefined;
734734

735735
/**
736736
* Style
@@ -841,7 +841,7 @@ export class ScrollView extends ScrollViewBase {
841841
* The options object has an animated prop, that enables the scrolling animation or not.
842842
* The animated prop defaults to true
843843
*/
844-
scrollToEnd(options?: {animated?: boolean}): void;
844+
scrollToEnd(options?: {animated?: boolean | undefined}): void;
845845

846846
/**
847847
* Displays the scroll indicators momentarily.

Libraries/Components/TextInput/InputAccessoryView.d.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ export class InputAccessoryView extends React.Component<InputAccessoryViewProps>
2323
export interface InputAccessoryViewProps {
2424
backgroundColor?: ColorValue | undefined;
2525

26-
children?: React.ReactNode;
26+
children?: React.ReactNode | undefined;
2727

2828
/**
2929
* An ID which is used to associate this InputAccessoryView to specified TextInput(s).

Libraries/Components/Touchable/TouchableWithoutFeedback.d.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ export interface TouchableWithoutFeedbackProps
4040
extends TouchableWithoutFeedbackPropsIOS,
4141
TouchableWithoutFeedbackPropsAndroid,
4242
AccessibilityProps {
43-
children?: React.ReactNode;
43+
children?: React.ReactNode | undefined;
4444

4545
/**
4646
* Delay in ms, from onPressIn, before onLongPress is called.

Libraries/Components/View/ViewAccessibility.d.ts

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -75,10 +75,10 @@ export interface AccessibilityProps
7575
*/
7676
accessibilityValue?: AccessibilityValue | undefined;
7777

78-
'aria-valuemax'?: AccessibilityValue['max'];
79-
'aria-valuemin'?: AccessibilityValue['min'];
80-
'aria-valuenow'?: AccessibilityValue['now'];
81-
'aria-valuetext'?: AccessibilityValue['text'];
78+
'aria-valuemax'?: AccessibilityValue['max'] | undefined;
79+
'aria-valuemin'?: AccessibilityValue['min'] | undefined;
80+
'aria-valuenow'?: AccessibilityValue['now'] | undefined;
81+
'aria-valuetext'?: AccessibilityValue['text'] | undefined;
8282
/**
8383
* When `accessible` is true, the system will try to invoke this function when the user performs an accessibility custom action.
8484
*/
@@ -105,7 +105,7 @@ export interface AccessibilityProps
105105
/**
106106
* Indicates to accessibility services to treat UI component like a specific role.
107107
*/
108-
role?: Role;
108+
role?: Role | undefined;
109109
}
110110

111111
export type AccessibilityActionInfo = Readonly<{

Libraries/Components/View/ViewPropTypes.d.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -173,7 +173,7 @@ export interface ViewProps
173173
Touchable,
174174
PointerEvents,
175175
AccessibilityProps {
176-
children?: React.ReactNode;
176+
children?: React.ReactNode | undefined;
177177
/**
178178
* This defines how far a touch event can start away from the view.
179179
* Typical interface guidelines recommend touch targets that are at least

0 commit comments

Comments
 (0)