首页 > 解决方案 > TypeScript 不会选择正确的覆盖

问题描述

我刚刚创建了一个动态组件,应该如下所示:

/* 应该继承所有 InputComponent 属性。DefaultComponent 应该是默认的组件道具值。*/

<DynamicComponent component={InputComponent} />

我当前的实现如下所示:

type DefaultProps = { defaultProp: string }
type InputProps = { onChange: () => void }
type DynamicType<P> = DynamicProps & { component: ReactType<P> } & P

export default function DynamicComponent(props: DynamicProps & { component?: DefaultComponent } & DefaultComponentProps): ReactElement<DefaultComponentProps>
export default function DynamicComponent<P>(props: DynamicType<P>): ReactElement<P> {
    const { style: overrideStyle, component } = props
    const { style } = getStyle(props)
    const mergedStyle = { ...style, ...overrideStyle }
    return React.createElement(component, { ...props, style: mergedStyle })
};

DynamicComponent.defaultProps = { component: DefaultComponent }

所以我希望接下来会发生:

1.)当组件未定义时,我希望第一次覆盖(默认的那个)

<DynamicComponent defaultProps='itsTotallyValid' /> // valid

2.) 定义组件时,我希望继承它的属性

<DynamicComponent component={InputComponent} onChange={() =>{}} /> // valid

由于某种原因,第二种情况永远不会发生,它总是选择第一种。有没有办法更严格,所以我可以强迫第二种情况成为可能?

更新

示例:https ://codesandbox.io/s/quiet-architecture-zx60y

标签: reactjstypescripttypescript-typingstypescript-genericsreact-tsx

解决方案


解决注释中关于默认泛型类型阻塞类型推断的问题,但事实并非如此,下面的最小示例演示了类型推断在T默认为 的类型上工作string

function Bar<T = string>(props: { component: T }) : T {
  return props.component
}

Bar({ component : 'string' })
Bar({ component : 5 }) // <-- Type inferred to be number

推荐阅读