reactjstypescript

How to infer union type from rest property?


I would like to get union type from rest property as a generic. I want to conditionally set return type of function based on that if there is at least one element in rest property which is not string or number.

type TTranslationResult<T> = T extends number | string
  ? string
  : ReactNode | ReactNode[];

export default function translate<T extends ReactNode = string>(
  key: TDictionaryKey,
  ...params: T[]
): TTranslationResult<T> {

...

}

I would expect T to be string | ReactNode when I send something like this to the function:

translate(
   'XXX',
   'some string',
   <LinkText href={`foo`}>
       {foo}
   </LinkText>
)

Instead it infers type of the first property in the array


Solution

  • I found out the solution. You have to expect T to be an array, not element of an array.

    type TTranslationResult<T> = T extends (number | string)[]
      ? string
      : ReactNode | ReactNode[];
    
    export default function translate<T extends ReactNode[] = string[]>(
      key: TDictionaryKey,
      ...params: T
    ): TTranslationResult<T> {
    {
    
    ...
    
    }