reactjs - 基于未定义属性的条件属性
我想让 TypeScript 根据根本没有传递的属性对缺失的属性发出警告。
请考虑以下示例:
type MyComponentProps = { isOpen: boolean } & (
| ({ withButton?: true | undefined | void | never } & { buttonText: string })
| ({ withButton?: false } & { buttonText?: never })
)
const MyComponent: React.FC<MyComponentProps> = ({ withButton = true, buttonText }) => {
return <></>
}
const AnotherComponent = () => {
// TypeScript does not complain, but I wanted it to require `buttonText` when `withButton` is not passed
return <MyComponent isOpen={false} />
}
有没有办法我可以修改条件 MyComponentProps,这样当我根本不传 withButton 时,它会要求 buttonText?
答案#1
当 withButton 的值为 false 时,你可以将其属性设为必需,这样就不会匹配缺失该属性的情况:
type MyComponentProps = { isOpen: boolean } & (
| ({ withButton?: true | undefined | never } & { buttonText: string }) // If withButton prop is true or missing, buttonText prop is required
| ({ withButton: false } & { buttonText?: never }) // If withButton prop is false, buttonText prop is forbidden (or at most undefined)
)
现在当缺少 withButton 属性时,TypeScript 会正确提示错误,但 buttonText 同样缺失时(也就是说现在它是必需的):
const AnotherComponent = () => {
return (<>
<MyComponent isOpen={false} />
{/*~~~~~~~~~ Property 'withButton' is missing in type '{ isOpen: false; }' but required in type '{ withButton: false; }'.(2322) */}
<MyComponent withButton={true} isOpen={false} />
{/*~~~~~~~~~ Property 'buttonText' is missing in type '{ withButton: true; isOpen: false; }' but required in type '{ buttonText: string; }'.(2322) */}
<MyComponent withButton={false} buttonText="should not be there" isOpen={false} />
{/*~~~~~~~~~ Type 'string' is not assignable to type 'undefined'.(2322) */}
<MyComponent withButton={false} isOpen={false} />{/* Okay */}
<MyComponent withButton={false} buttonText={undefined} isOpen={false} />{/* Okay */}
<MyComponent withButton={true} buttonText="okay" isOpen={false} />{/* Okay */}
<MyComponent withButton={undefined} buttonText="okay as well" isOpen={false} />{/* Okay */}
</>)
}
游乐场链接
`
<MyComponent isOpen={false} />期望withButton,但我希望它期望buttonText`
如果你的意思是你希望 TS 错误提示的是 buttonText 而不是 withButton,那么只需确保在联合类型中将你希望 TS 默认用于提示的类型放在最后即可:
type MyComponentProps = { isOpen: boolean } & (
| ({ withButton: false } & { buttonText?: never }) // If withButton prop is false, buttonText prop is forbidden (or at most undefined)
// Put last in union the type that you want to hint to by default
| ({ withButton?: true | undefined | never } & { buttonText: string }) // If withButton prop is true or missing, buttonText prop is required
)
const AnotherComponent = () => {
return (<>
<MyComponent isOpen={false} />
{/*~~~~~~~~~ Property 'buttonText' is missing in type '{ isOpen: false; }' but required in type '{ buttonText: string; }'.(2322) */}
<MyComponent buttonText="okay as well again" isOpen={false} />{/* Okay */}
</>)
}
游乐场链接
