Слияние несовместимых типов. пример: тип '{}' не может быть назначен типу {{} ' - PullRequest
0 голосов
/ 12 апреля 2020

Как объединить типы

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 из Touchable Highlight / Opacity не распознается.

Результат при выводе типа (без назначения типа для 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)

1 Ответ

0 голосов
/ 14 апреля 2020

Как вы поясните в своем комментарии , вы бы хотели иметь возможность менять различные реализации Touchable внутри своего пользовательского компонента 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"
  />
);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...