1

My question is kinda to my previous one: ReactTS extend type by dynamic Component Props?

So lets say I've got the next lines:

type Base = {
    baseProp: ...
}

type Extend = {
    extendProp: ...
}

// use this if "as" undefined
type DefaultPropsToExtend = {
    defaultToExtendProp: ...
}

declare const ExtendedComponent: React.FC<Extend>
declare const DefaultExtendedComponent: React.FC<DefaultPropsToExtend>

function Base<T = DefaultPropsToExtend>(props: BaseProps & { as: React.ComponentType<T> } & T): React.ReactElement {
    const Wrapper = props.as
    return <Wrapper />
}

So what I expect when I call the next lines are:

<Base /> // props can be => { baseProp, defaultToExtendProp }

What props actually I am seeing => { baseProp }

If I am doing the next then things working property, but this way I need to be explicit about the default "as" every time.
<Base as={DefaultToExtendComponent} /> // => { baseProp, defaultToExtendProp }

1 Answer 1

1

Probably the best option is to use overloads. One overload can be generic and accept any component. The other overload can have the default:

type BaseProps = {
    baseProp: string
}

type Extend = {
    extendProp: number
}

// use this if "as" undefined
type DefaultPropsToExtend = {
    defaultToExtendProp: number
}

declare const ExtendedComponent: React.FC<Extend>
declare const DefaultExtendedComponent: React.FC<DefaultPropsToExtend>

function Base(props: BaseProps & DefaultPropsToExtend): React.ReactElement
function Base<T>(props: BaseProps & { as: React.ComponentType<T> } & T): React.ReactElement
function Base<T = DefaultPropsToExtend>(props: BaseProps & { as?: React.ComponentType<T> } & T): React.ReactElement {
    const Wrapper = props.as || (DefaultExtendedComponent as unknown as React.ComponentType<T>)
    return <Wrapper {...props as T}/>
}

let a = <Base baseProp="" defaultToExtendProp={0} />
let a2 = <Base as={DefaultExtendedComponent} defaultToExtendProp={0} baseProp="" />
Sign up to request clarification or add additional context in comments.

1 Comment

Man, you are an absolute saviour! As I am kinda new to TS I did not know I could do this (even if I would know, most likely wouldn't come up with this lol) Thanks once again!!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.