如何合并类型
type TheseTypes = typeof TouchableNativeFeedback &
typeof TouchableWithoutFeedback &
typeof TouchableHighlight &
typeof TouchableOpacity;
const Button: React.FC<CustomProps> = (props) => {
const ButtonInstance: TheseTypes =
props.highlight
? TouchableHighlight
: props.nativeFeedback
? TouchableNativeFeedback
: props.withoutFeedback
? TouchableWithoutFeedback
: TouchableOpacity;
return (
<ButtonInstance
{...props}
activeOpacity={props.opacity}>
{props.children}
</ButtonInstance>
);
};
我已经尝试过使用并集、交集、Partial<T>
和自定义type Subtract<T, K> = Pick<T, Exclude<keyof T, keyof K>>
案例0-道具不完整
无法识别来自可触摸高光/不透明度的activeOpacity
。
类型推断的结果(不向RenderButton分配类型(
(JSX attribute) activeOpacity: number
No overload matches this call.
Overload 1 of 2, '(props: Readonly<TouchableNativeFeedbackProps>): TouchableWithoutFeedback | TouchableNativeFeedback', gave the following error.
Type '{ children: ReactNode; disabled: any; activeOpacity: number; style: any; }' is not assignable to type 'IntrinsicAttributes & IntrinsicClassAttributes<TouchableWithoutFeedback | TouchableNativeFeedback> & Readonly<...> & Readonly<...> & Readonly<...> & Readonly<...>'.
Property 'activeOpacity' does not exist on type 'IntrinsicAttributes & IntrinsicClassAttributes<TouchableWithoutFeedback | TouchableNativeFeedback> & Readonly<...> & Readonly<...> & Readonly<...> & Readonly<...>'.
Overload 2 of 2, '(props: TouchableNativeFeedbackProps, context?: any): TouchableWithoutFeedback | TouchableNativeFeedback', gave the following error.
Type '{ children: ReactNode; disabled: any; activeOpacity: number; style: any; }' is not assignable to type 'IntrinsicAttributes & IntrinsicClassAttributes<TouchableWithoutFeedback | TouchableNativeFeedback> & Readonly<...> & Readonly<...> & Readonly<...> & Readonly<...>'.
Property 'activeOpacity' does not exist on type 'IntrinsicAttributes & IntrinsicClassAttributes<TouchableWithoutFeedback | TouchableNativeFeedback> & Readonly<...> & Readonly<...> & Readonly<...> & Readonly<...>'.ts(2769)
|
上的结果
同上。
情况1-道具正常,错误行5
在声明const RenderButton
时,我在下面收到了这些错误,但VSCode Intellisense建议使用正确的道具。
&
的结果
Type 'TouchableWithoutFeedback' is missing the following properties from type 'TouchableHighlight': measure, measureInWindow, measureLayout, setNativeProps, and 2 more.ts(2322)
Partial<>&
上的结果
Types of property 'prototype' are incompatible.
Type 'TouchableWithoutFeedback' is missing the following properties from type 'TouchableHighlight': measure, measureInWindow, measureLayout, setNativeProps, and 2 more.ts(2322)
Partial<>|
上的结果
Type 'typeof TouchableNativeFeedback' is not assignable to type 'Partial<typeof TouchableWithoutFeedback> | Partial<typeof TouchableHighlight> | Partial<TouchableNativeFeedback> | Partial<...>'.
Type 'typeof TouchableNativeFeedback' is not assignable to type 'Partial<typeof TouchableOpacity>'.
Types of property 'prototype' are incompatible.
Type 'TouchableNativeFeedback' is missing the following properties from type 'TouchableOpacity': setOpacityTo, setTimeout, clearTimeout, setInterval, and 11 more.ts(2322)
正如您在评论中所解释的,您希望能够在自定义Button组件中交换Touchable的不同实现。
这是一个有趣的问题。我将建议一种稍微不同的方法,即我们不必尝试将不同的可触摸类型组合/联合。
相反,我们将允许提供任何组件作为包装器(如果需要,这可能仅限于Touchables(,并且道具将根据该组件类型进行调整。在内部,你可以按照你想要的方式布局按钮,添加图标、标题等,并为它们添加额外的道具。
import React from 'react';
import { TouchableOpacity, Text } from 'react-native';
import { TouchableWithoutFeedback } from 'react-native-gesture-handler';
// this type is generic over some arbitrary element type and will 'extend' its props
type Props<T extends React.ElementType> = React.ComponentProps<T> & {
Touchable?: T;
title: string;
};
// this component is generic but you do not need to pass the generic parameter inside jsx (will be inferred from the Touchable prop)
const Button = <T extends React.ElementType>({
Touchable = TouchableOpacity,
title,
...props
}: Props<T>) => (
<Touchable {...props}>
<Text>{title}</Text>
</Touchable>
);
// the component can then be used like so:
const ButtonOpacity = (
<Button activeOpacity={0} onPress={() => {}} title="title" />
);
// here we have an error - property `activeOpacity` does not exist on this type
const ButtonWithoutFeedback = (
<Button
Touchable={TouchableWithoutFeedback}
activeOpacity={10}
onPress={() => {}}
title="title"
/>
);