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 />
}