【问题标题】:Reject parameters in a function that have specific type in a prop拒绝在道具中具有特定类型的函数中的参数
【发布时间】:2021-08-04 02:42:58
【问题描述】:

我有一个组件已准备好接收名为 type 的参数,该参数可以是 email、mobileNumber、cep、password' 四个选项之一。如果 属性类型值密码,则不应解析属性图标和 onPressIcon。我将这个道具输入如下:

type TextInputT = {
  type: 'email' | 'mobileNumber' | 'cep' | 'password';
  name: string;
  label: string;
  onPressIcon: () => void;
  icon: string;
};

如果 textinput 的类型是密码,如何使道具 icononPressIcon 无效?

我已经试过了

type TextInput = {
  type: 'password';
  name: string;
  label: string;
};

type CustomTextInput = {
  type: 'email' | 'mobileNumber' | 'cep';
  name: string;
  label: string;
  onPressIcon: () => void;
  icon: string;
};

export type TextInputT = TextInput | CustomTextInput;

但在组件道具类型分配中抛出错误如下

EDIT1:我的 TextInput.tsx

const TextInput: React.FC<TextInputT> = ({
  type,
  name,
  label,
  onPressIcon,
  icon,
}) => {
  const inputValueRef = React.useRef(null);

  const [isFocused, setIsFocused] = React.useState<boolean>(false);
  const [valueShown, setValueShown] = React.useState<boolean>(false);

  const [field, meta, helpers] = useField(name);

  const hasError: boolean = meta.touched && typeof meta.error !== 'undefined';
  const error: string = meta.touched && meta.error;

  return (
    <Container>
      <Content
        active={isFocused}
        error={hasError}
        disabled={false}
        onPress={() => inputValueRef?.current?.focus()}
        activeOpacity={1}>
        {(isFocused || meta.touched) && (
          <Label active={isFocused} error={hasError} disabled={false}>
            {label}
          </Label>
        )}
        <InputBox>
          <InputValue
            ref={inputValueRef}
            secureTextEntry={type === 'password' && !valueShown}
            onFocus={() => setIsFocused(true)}
            placeholder={!isFocused ? label : ''}
            value={getFormattedValue({
              value: field.value,
              mask: type,
            })}
            onChangeText={field.onChange(name)}
            onBlur={() => [setIsFocused(false), helpers.setTouched(true)]}
          />
          {type === 'password' && (
            <IconBox onPress={() => setValueShown(!valueShown)}>
              <IconDynamic
                name={`${valueShown ? 'EyeClosed' : 'Eye'}`}
                width={24}
                height={24}
                fill={colors.C.default}
              />
            </IconBox>
          )}
          {icon && onPressIcon && (
            <IconBox onPress={onPressIcon}>
              <IconDynamic
                name={icon}
                width={24}
                height={24}
                fill={colors.C.default}
              />
            </IconBox>
          )}
        </InputBox>
      </Content>
      {hasError && (
        <ErrorBox>
          <TextError>{error}</TextError>
        </ErrorBox>
      )}
    </Container>
  );
};

export default TextInput;

【问题讨论】:

标签: typescript react-native react-typescript


【解决方案1】:

对于 TS,更安全的选择是在您检查 type 属性之前禁止使用 onPressIcon

type TextInput = {
  type: 'password';
  name: string;
  label: string;
};

type CustomTextInput = {
  type: 'email' | 'mobileNumber' | 'cep';
  name: string;
  label: string;
  onPressIcon: () => void;
  icon: string;
};

export type Union = TextInput | CustomTextInput;

const comp=(prop:Union)=>{
    if(prop.type==='password'){
        const x = prop.onPressIcon // error
    }
    if(prop.type==='email'){
        const x = prop.onPressIcon // ok
    }
}

为了更好地理解它,请看下一个例子:

type TextInput = {
  type: 'password';
  name: string;
  label: string;
};

type CustomTextInput = {
  type: 'email' | 'mobileNumber' | 'cep';
  name: string;
  label: string;
  onPressIcon: () => void;
  icon: string;
};

export type Union = TextInput | CustomTextInput;

type Keys = keyof Union // "type" | "name" | "label" < ------ only properties which are common for both type

想象一下,TS 允许您在不检查 type 属性的情况下获取 onPressIcon 属性。

它会打破工会的整个想法。

【讨论】:

  • 太棒了,在这种情况下,现在显然是联合的概念,但我仍然很困惑如果类型是密码,如何使图标和 onPressIcon 无效:(
  • @MuriloMedeiros 我不确定invalidate 是什么意思。你能举个例子吗?
猜你喜欢
  • 2021-06-16
  • 1970-01-01
  • 1970-01-01
  • 2010-10-04
  • 2015-06-14
  • 1970-01-01
  • 2014-03-11
  • 1970-01-01
相关资源
最近更新 更多