From 50a481d23ae72a434849d2c85007e411b0c2bb1f Mon Sep 17 00:00:00 2001 From: Tim Yung Date: Tue, 17 Jul 2018 17:54:27 -0700 Subject: [PATCH] RN: Refine `StyleSheet.compose` Flow Type Summary: Refines `StyleSheet.compose` so that subtypes of `DangerouslyImpreciseStyleProp` can flow through the function call without losing their type. This makes it so that if you supply two `ViewStyleProp` types, you will get a `ViewStyleProp` type out of it. Reviewed By: TheSavior Differential Revision: D8851699 fbshipit-source-id: e38e572e363a71fddf63d6b6bf5a96b3cdae5915 --- Libraries/StyleSheet/StyleSheet.js | 10 +-- .../__flowtests__/StyleSheet-flowtest.js | 82 +++++++++++++++++++ 2 files changed, 87 insertions(+), 5 deletions(-) create mode 100644 Libraries/StyleSheet/__flowtests__/StyleSheet-flowtest.js diff --git a/Libraries/StyleSheet/StyleSheet.js b/Libraries/StyleSheet/StyleSheet.js index 4384ce9dbfc05d..f06337e2867ccc 100644 --- a/Libraries/StyleSheet/StyleSheet.js +++ b/Libraries/StyleSheet/StyleSheet.js @@ -272,12 +272,12 @@ module.exports = { * array, saving allocations and maintaining reference equality for * PureComponent checks. */ - compose( - style1: ?DangerouslyImpreciseStyleProp, - style2: ?DangerouslyImpreciseStyleProp, - ): ?DangerouslyImpreciseStyleProp { + compose( + style1: ?T, + style2: ?T, + ): ?T | $ReadOnlyArray { if (style1 != null && style2 != null) { - return [style1, style2]; + return ([style1, style2]: $ReadOnlyArray); } else { return style1 != null ? style1 : style2; } diff --git a/Libraries/StyleSheet/__flowtests__/StyleSheet-flowtest.js b/Libraries/StyleSheet/__flowtests__/StyleSheet-flowtest.js new file mode 100644 index 00000000000000..d4d5e5f3594f6c --- /dev/null +++ b/Libraries/StyleSheet/__flowtests__/StyleSheet-flowtest.js @@ -0,0 +1,82 @@ +/** + * Copyright (c) 2015-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + * + * @flow strict-local + * @format + */ + +'use strict'; + +const StyleSheet = require('StyleSheet'); + +import type {ImageStyleProp, TextStyleProp} from 'StyleSheet'; + +const imageStyle = {tintColor: 'rgb(0, 0, 0)'}; +const textStyle = {color: 'rgb(0, 0, 0)'}; + +module.exports = { + testGoodCompose() { + (StyleSheet.compose( + imageStyle, + imageStyle, + ): ImageStyleProp); + + (StyleSheet.compose( + textStyle, + textStyle, + ): TextStyleProp); + + (StyleSheet.compose( + null, + null, + ): TextStyleProp); + + (StyleSheet.compose( + textStyle, + null, + ): TextStyleProp); + + (StyleSheet.compose( + textStyle, + Math.random() < 0.5 ? textStyle : null, + ): TextStyleProp); + + (StyleSheet.compose( + [textStyle], + null, + ): TextStyleProp); + + (StyleSheet.compose( + [textStyle], + null, + ): TextStyleProp); + + (StyleSheet.compose( + [textStyle], + [textStyle], + ): TextStyleProp); + }, + + testBadCompose() { + // $FlowExpectedError - Incompatible type. + (StyleSheet.compose( + textStyle, + textStyle, + ): ImageStyleProp); + + (StyleSheet.compose( + // $FlowExpectedError - Incompatible type. + [textStyle], + null, + ): ImageStyleProp); + + // $FlowExpectedError - Incompatible type. + (StyleSheet.compose( + Math.random() < 0.5 ? textStyle : null, + null, + ): ImageStyleProp); + }, +};