Sharcoux
Sharcoux

Reputation: 6105

Using Exclude on inferred type results in 'never' in typescript

My goal is to be able to preconfigure some props of a component in a function, and have that function return a component that won't require the preconfigurated props. Here is a code illustrating that: (here is the playground):

function createExtendedComp<Props>(Comp: (props: Props) => any) {
  const ExtendendComp = (props: Props) => {
    return Comp(props)
  }
  ExtendendComp.attrs = <Result extends Partial<Props>>(attrs: Result) => {
    const PreconfiguratedComp = (props: Exclude<Props, Result>) => {
      return Comp({...props, ...attrs})
    }
    return PreconfiguratedComp
  }
  return ExtendendComp
}

function Comp (props: { test: string, style: string }) {
  return props
}
const PreconfigComp = createExtendedComp(Comp).attrs({ test: 'ok' })
PreconfigComp({ style: 'test' }) // <- Argument of type '{ style: string; }' is not assignable to parameter of type 'never'.

There seem to be a problem with the type inferred for Result. Typescript thinks that it should be never, while I would expect it to be { style: string }

How can I remove from Props the parts that are already handled in Result?

Upvotes: 0

Views: 145

Answers (1)

Federkun
Federkun

Reputation: 36964

I don't think you want to use Exclude here, but Omit.

    const PreconfiguratedComp = (props: Omit<Props, keyof Result>) => {

Something along the lines of:

function createExtendedComp<Props>(Comp: (val: Props) => any) {
  const ExtendendComp = (props: Props) => {
    return Comp(props)
  }

  ExtendendComp.attrs = <Result extends Partial<Props>>(attrs: Result) => {
    const PreconfiguratedComp = (props: Omit<Props, keyof Result>) => {
      return Comp({...props, ...attrs} as Props)
    }

    return PreconfiguratedComp
  }

  return ExtendendComp
}

Upvotes: 1

Related Questions