fix(TypeScript): Allow readonly arrays in transform (#46310)

Summary:
Currently readonly arrays aren't allowed in components' style, but readonly objects are accepted. This becomes evident in such case:

```ts
import { View } from 'react-native';

interface AppProps {
  transform: readonly ({ translateX: number } | { translateY: number })[];
  shadowOffset: Readonly<{ width: number; height: number }>;
}

export default function App({ transform, shadowOffset }: AppProps) {
  return (
    <>
      {/* TypeScript error with transform */}
      <View style={{ transform }} />
      {/* No errors with shadowOffset */}
      <View style={{ shadowOffset }} />
    </>
  );
}
```

## Changelog:

[GENERAL] [FIXED] - Allow readonly array type for transform property

Pull Request resolved: https://github.com/facebook/react-native/pull/46310

Test Plan:
`yarn test-typescript`

I added relevant tests cases.

Reviewed By: robhogan

Differential Revision: D62140462

Pulled By: NickGerleman

fbshipit-source-id: 87374b0901ebc40cab48d442b61fe7a65711bc89
This commit is contained in:
Tomasz Żelawski
2024-09-03 14:50:24 -07:00
committed by Facebook GitHub Bot
parent 2b11131247
commit c16defaff2
2 changed files with 30 additions and 16 deletions
@@ -182,21 +182,23 @@ type MaximumOneOf<T, K extends keyof T = keyof T> = K extends keyof T
export interface TransformsStyle {
transform?:
| MaximumOneOf<
PerspectiveTransform &
RotateTransform &
RotateXTransform &
RotateYTransform &
RotateZTransform &
ScaleTransform &
ScaleXTransform &
ScaleYTransform &
TranslateXTransform &
TranslateYTransform &
SkewXTransform &
SkewYTransform &
MatrixTransform
>[]
| Readonly<
MaximumOneOf<
PerspectiveTransform &
RotateTransform &
RotateXTransform &
RotateYTransform &
RotateZTransform &
ScaleTransform &
ScaleXTransform &
ScaleYTransform &
TranslateXTransform &
TranslateYTransform &
SkewXTransform &
SkewYTransform &
MatrixTransform
>[]
>
| string
| undefined;
transformOrigin?: Array<string | number> | string | undefined;
@@ -8,7 +8,7 @@
*/
import * as React from 'react';
import {View, StyleSheet} from 'react-native';
import {View, StyleSheet, type ShadowStyleIOS} from 'react-native';
export function App() {
return <View style={styles.container} />;
@@ -40,3 +40,15 @@ const styles2 = StyleSheet.create({
magrinRight: 1,
},
});
const shadowOffsetConst: Readonly<ShadowStyleIOS['shadowOffset']> = {
width: 1,
height: 2,
};
const styles3 = StyleSheet.create({
transforms: {
transform: [{translateX: 40}] as const,
shadowOffset: shadowOffsetConst,
},
});