Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/410.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 为什么';当我省略/需要道具时,我不会歧视工会工作吗?_Javascript_Reactjs_Typescript - Fatal编程技术网

Javascript 为什么';当我省略/需要道具时,我不会歧视工会工作吗?

Javascript 为什么';当我省略/需要道具时,我不会歧视工会工作吗?,javascript,reactjs,typescript,Javascript,Reactjs,Typescript,我有一个基于特定属性呈现不同元素的组件,称为type。它可以有如下类型定义: interface CommonProps { size: 'lg' | 'md' | 'sm'; } interface SelectInputProps extends CommonProps { type: 'select'; options: readonly Option[]; selected: string; } interface TextInputProps extends Com

我有一个基于特定属性呈现不同元素的组件,称为
type
。它可以有如下类型定义:

interface CommonProps {
  size: 'lg' | 'md' | 'sm';
}

interface SelectInputProps extends CommonProps {
  type: 'select';
  options: readonly Option[];
  selected: string;
}

interface TextInputProps extends CommonProps {
  type: 'text';
  value: string;
};

type InputProps = (SelectInputProps | TextInputProps) & ExtraProps;

function Field(props: InputProps): JSX.Element;
现在在我自己的组件中,我将访问此组件的属性,如下所示:

import { ComponentProps } from 'react';

type FieldProps = ComponentProps<typeof Field>;

function MySpecialField(props: FieldProps) {
  if (props.type === 'select') {
    // this works
    const { options, selected } = props;
  }
  return <Field {...props} />
}

为什么会这样?有办法解决吗?

这是因为它不在
T
中分布。使用
keyof T
,当
T
是一个联合体时,
keyof T
仅是联合体所有成员中存在的那些键(
keyof T
T
中是逆变的,因此
keyof(a | B)
相当于
(a)&(B)
)。这正按照预期工作

幸运的是,如果您想要一个分布式版本的
省略
,您可以使用:

类型DistributiveOmit=
有吗?省略:从不;
然后你可以看到行为的变化:

type MyFieldProps = DistributiveOmit<React.ComponentProps<typeof Field>, 'a'>;
/* type MyFieldProps = Omit<{
    type: 'select';
    options: Option[];
} & ExtraProps, "a"> | Omit<{
    type: 'text';
    value: string;
} & ExtraProps, "a"> */
类型MyFieldProps=DistributiveOmit;
/*键入MyFieldProps=Omit | Omit*/
这使您的代码开始工作:

function MyField(props: MyFieldProps) {
  if (props.type === 'select') {
    const options = props.options;    // okay
  }
  return <input />
}
函数MyField(道具:MyFieldProps){
如果(props.type==='select'){
const options=props.options;//好的
}
返回
}

函数MyField(道具:MyFieldProps){
如果(props.type==='select'){
//问题出在这里
const options=props.options;
}
返回
}

对于
Required
和其他实用程序类型也可以这样做,对吗?是的,您可以使用类似
type distributive=T extends any的东西在联合体之间进行分配?非分发:从不
type MyFieldProps = DistributiveOmit<React.ComponentProps<typeof Field>, 'a'>;
/* type MyFieldProps = Omit<{
    type: 'select';
    options: Option[];
} & ExtraProps, "a"> | Omit<{
    type: 'text';
    value: string;
} & ExtraProps, "a"> */
function MyField(props: MyFieldProps) {
  if (props.type === 'select') {
    const options = props.options;    // okay
  }
  return <input />
}
function MyField(props: MyFieldProps) {
  if (props.type === 'select') {
    // Here's the problem
    const options = props.options;
  }
  return <input />
}