Javascript 如何使用typescript从复杂类型中解构?

Javascript 如何使用typescript从复杂类型中解构?,javascript,reactjs,typescript,Javascript,Reactjs,Typescript,考虑一下这个用例:我有一个React功能组件,我想在分解道具的情况下实现它(为了与所有其他组件保持一致) 这是一个复选框,有两个可能的角色。如果它与全部数据关联,则可以与之交互;如果它与有限的数据关联,则将显示一个名称,但无法与元素交互 这可以简单地通过使用两个独立的组件来实现,我可能会采用这种方法,但我想知道以这种方式在代码中扩展和充实现有组件的可能性有多大 所以,我从一个复选框组件开始,它将这种类型作为道具: export interface CheckboxProps { checke

考虑一下这个用例:我有一个React功能组件,我想在分解道具的情况下实现它(为了与所有其他组件保持一致)

这是一个复选框,有两个可能的角色。如果它与全部数据关联,则可以与之交互;如果它与有限的数据关联,则将显示一个名称,但无法与元素交互

这可以简单地通过使用两个独立的组件来实现,我可能会采用这种方法,但我想知道以这种方式在代码中扩展和充实现有组件的可能性有多大

所以,我从一个复选框组件开始,它将这种类型作为道具:

export interface CheckboxProps {
  checked: boolean;
  id: string;
  disabled?: boolean;
  disabledTooltipLabel?: string;
  onChange: VoidFunction;
  labelOrientation?: CheckboxLabelOrientation;
  label?: string;
  className?: string;
}
通过对道具的分解,开始功能组件定义:

export const Checkbox: React.FunctionComponent<CheckboxProps> = ({
  checked,
  disabled,
  disabledTooltipLabel,
  id,
  onChange,
  labelOrientation = "left",
  label = "",
  className,
}) => {
...

这似乎是一个改进,但它仍然有一个类型强制转换,不能在arrow函数参数中直接分解。有办法避免吗?我喜欢这样为函数组件的道具保留一个有用的类型约定,这在这里很重要。

当您有一个像
CheckboxBarebones | CheckboxProps
这样的联合类型时,您通常希望在分解结构之前缩小类型。这是因为当你分解结构时,你正在使每个属性成为它自己的独立变量。因此,检查是否存在
checked
不会细化任何其他属性类型。如果在分解结构之前知道特定类型,那么属性将根据对象类型获得正确的类型

您还应该知道,由于
label
是一个可选属性,
Pick
可以满足空对象的要求。我假设您打算让它成为
CheckboxBarebones
所必需的

如果我们定义了一个类型联合,要求它实现两种类型中的一种,但还包括所有可选属性,那么您将能够分解结构。请注意,您不能简单地在这两种类型之间切换,并且必须假设所有这些变量都可能是未定义的

type EitherCheckboxProps = (CheckboxProps | {label: string}) & Partial<CheckboxProps>

export const Checkbox: React.FunctionComponent<EitherCheckboxProps> = ({
  checked,
  disabled,
  disabledTooltipLabel,
  id,
  onChange,
  labelOrientation = "left",
  label = "",
  className,
}) => {
键入EitherCheckboxProps=(CheckboxProps{label:string})和Partial
导出常量复选框:React.FunctionComponent=({
选中的,
残废
禁用Tooltiplabel,
身份证件
一旦改变,
labelOrientation=“左”,
label=“”,
类名,
}) => {

您可以为消费者保留所需的道具类型,但在实现中,您可以将其定义为部分道具,而无需强制转换:

const Checkbox: React.FC<Pick<CheckboxProps, "label"> | CheckboxProps> = ({
  label,
  checked,
  disabled,
  disabledTooltipLabel,
  id,
  onChange,
  labelOrientation = "left",
  className,
}: Partial<CheckboxProps>) => {
    return <>...</>;
}
const复选框:React.FC=({
标签,
选中的,
残废
禁用Tooltiplabel,
身份证件
一旦改变,
labelOrientation=“左”,
类名,
}:部分)=>{
返回。。。;
}

所以你基本上是说,为了让我用函数参数解构,我需要将它与
部分
结合起来?我认为这不符合我的要求,因为我试图在这里保留类型契约,我希望确保两组参数中的一组被发送进来,如果其中一些参数被重新发送,我会拒绝缺少必需的。关于标签的观点很好,我发布问题的方式有点考虑不周。我们需要联合
(CheckboxProps{label:string})
Partial
,因此它仍然必须满足联合体中的一种类型。您必须以某种方式在仅标签的情况下定义这些键的值,以便对其进行分解。您可以将它们定义为
从不
未定义的
,而不是可选的,但您必须以某种方式定义它们。
type EitherCheckboxProps = (CheckboxProps | {label: string}) & Partial<CheckboxProps>

export const Checkbox: React.FunctionComponent<EitherCheckboxProps> = ({
  checked,
  disabled,
  disabledTooltipLabel,
  id,
  onChange,
  labelOrientation = "left",
  label = "",
  className,
}) => {
const Checkbox: React.FC<Pick<CheckboxProps, "label"> | CheckboxProps> = ({
  label,
  checked,
  disabled,
  disabledTooltipLabel,
  id,
  onChange,
  labelOrientation = "left",
  className,
}: Partial<CheckboxProps>) => {
    return <>...</>;
}