From 34243a53af672877a27136c7aa14c74f1af1a7e3 Mon Sep 17 00:00:00 2001 From: _nderscore <_@nderscore.com> Date: Sat, 22 Jul 2023 10:53:39 -0400 Subject: [PATCH] fix: make web platform types compatible with native types (#2091) When react-native-svg is used on a web project where typescript has been configured to resolve .web.ts file exentions before .ts, it causes type errors. This is because the types in ReactNativeSVG.web.ts don't match the types in ReactNativeSVG.ts This PR adds the correct types for all exported components on the web platform inside ReactNativeSVG.web.ts. Those changes are: Added missing prop types for all components Made style, gradientTransform, and patternTransform optional in BaseProps. Made styleProp argument of resolve() undefined-able, to support style being an optional prop (this also seems to follow the logic in the body of the function, which has a check for a truthy styleProp) These changes only impact types - no functionality has been changed. --- src/ReactNativeSVG.web.ts | 89 ++++++++++++++++++++++----------------- src/lib/resolve.ts | 5 ++- 2 files changed, 54 insertions(+), 40 deletions(-) diff --git a/src/ReactNativeSVG.web.ts b/src/ReactNativeSVG.web.ts index 7e951204..de57b707 100644 --- a/src/ReactNativeSVG.web.ts +++ b/src/ReactNativeSVG.web.ts @@ -1,4 +1,27 @@ import * as React from 'react'; +import type { CircleProps } from './elements/Circle'; +import type { ClipPathProps } from './elements/ClipPath'; +import type { EllipseProps } from './elements/Ellipse'; +import type { ForeignObjectProps } from './elements/ForeignObject'; +import type { GProps } from './elements/G'; +import type { ImageProps } from './elements/Image'; +import type { LineProps } from './elements/Line'; +import type { LinearGradientProps } from './elements/LinearGradient'; +import type { MarkerProps } from './elements/Marker'; +import type { MaskProps } from './elements/Mask'; +import type { PathProps } from './elements/Path'; +import type { PatternProps } from './elements/Pattern'; +import type { PolygonProps } from './elements/Polygon'; +import type { PolylineProps } from './elements/Polyline'; +import type { RadialGradientProps } from './elements/RadialGradient'; +import type { RectProps } from './elements/Rect'; +import type { StopProps } from './elements/Stop'; +import type { SvgProps } from './elements/Svg'; +import type { SymbolProps } from './elements/Symbol'; +import type { TextProps } from './elements/Text'; +import type { TextPathProps } from './elements/TextPath'; +import type { TSpanProps } from './elements/TSpan'; +import type { UseProps } from './elements/Use'; import type { GestureResponderEvent, TransformsStyle } from 'react-native'; import { // @ts-ignore @@ -65,11 +88,11 @@ interface BaseProps { forwardedRef?: | React.RefCallback | React.MutableRefObject; - style: Iterable<{}>; + style?: Iterable<{}>; // different tranform props - gradientTransform: TransformProps['transform']; - patternTransform: TransformProps['transform']; + gradientTransform?: TransformProps['transform']; + patternTransform?: TransformProps['transform']; } const hasTouchableProperty = (props: BaseProps) => @@ -372,11 +395,11 @@ export class WebShape< } } -export class Circle extends WebShape { +export class Circle extends WebShape { tag = 'circle' as const; } -export class ClipPath extends WebShape { +export class ClipPath extends WebShape { tag = 'clipPath' as const; } @@ -384,25 +407,13 @@ export class Defs extends WebShape { tag = 'defs' as const; } -export class Ellipse extends WebShape { +export class Ellipse extends WebShape { tag = 'ellipse' as const; } -export class G extends WebShape< - BaseProps & { - x?: NumberProp; - y?: NumberProp; - translate?: string; - } -> { +export class G extends WebShape { tag = 'g' as const; - prepareProps( - props: BaseProps & { - x?: NumberProp; - y?: NumberProp; - translate?: string; - }, - ) { + prepareProps(props: BaseProps & GProps) { const { x, y, ...rest } = props; if ((x || y) && !rest.translate) { @@ -413,39 +424,39 @@ export class G extends WebShape< } } -export class Image extends WebShape { +export class Image extends WebShape { tag = 'image' as const; } -export class Line extends WebShape { +export class Line extends WebShape { tag = 'line' as const; } -export class LinearGradient extends WebShape { +export class LinearGradient extends WebShape { tag = 'linearGradient' as const; } -export class Path extends WebShape { +export class Path extends WebShape { tag = 'path' as const; } -export class Polygon extends WebShape { +export class Polygon extends WebShape { tag = 'polygon' as const; } -export class Polyline extends WebShape { +export class Polyline extends WebShape { tag = 'polyline' as const; } -export class RadialGradient extends WebShape { +export class RadialGradient extends WebShape { tag = 'radialGradient' as const; } -export class Rect extends WebShape { +export class Rect extends WebShape { tag = 'rect' as const; } -export class Stop extends WebShape { +export class Stop extends WebShape { tag = 'stop' as const; } @@ -468,7 +479,7 @@ function encodeSvg(svgString: string) { .replace(/\s+/g, ' '); } -export class Svg extends WebShape { +export class Svg extends WebShape { tag = 'svg' as const; toDataURL( callback: (data: string) => void, @@ -512,39 +523,39 @@ export class Svg extends WebShape { } } -export class Symbol extends WebShape { +export class Symbol extends WebShape { tag = 'symbol' as const; } -export class Text extends WebShape { +export class Text extends WebShape { tag = 'text' as const; } -export class TSpan extends WebShape { +export class TSpan extends WebShape { tag = 'tspan' as const; } -export class TextPath extends WebShape { +export class TextPath extends WebShape { tag = 'textPath' as const; } -export class Use extends WebShape { +export class Use extends WebShape { tag = 'use' as const; } -export class Mask extends WebShape { +export class Mask extends WebShape { tag = 'mask' as const; } -export class ForeignObject extends WebShape { +export class ForeignObject extends WebShape { tag = 'foreignObject' as const; } -export class Marker extends WebShape { +export class Marker extends WebShape { tag = 'marker' as const; } -export class Pattern extends WebShape { +export class Pattern extends WebShape { tag = 'pattern' as const; } diff --git a/src/lib/resolve.ts b/src/lib/resolve.ts index 5af8c951..3a9cb69b 100644 --- a/src/lib/resolve.ts +++ b/src/lib/resolve.ts @@ -1,7 +1,10 @@ import { StyleSheet } from 'react-native'; // Kept in separate file, to avoid name collision with Symbol element -export function resolve(styleProp: Iterable, cleanedProps: T) { +export function resolve( + styleProp: Iterable | undefined, + cleanedProps: T, +) { if (styleProp) { return StyleSheet ? [styleProp, cleanedProps]