Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

React memo function changes the props type of the component?

I have encountered a very weird problem. I have defined two components. If these two components are written in one file, there will be no compilation errors. However, if the two components are written separately, compilation errors will occur.

test3.tsx

import React from "react";

type ValueType = number[] | string[] | number | string

interface ISelectChipProps<X extends ValueType> {
  value: X
  setValue: (value: X) => void
}

const SelectChip = <X extends ValueType>({
  value,
  setValue,
}: ISelectChipProps<X>) => {

  return (
    <></>
  )
}

interface IFilterProps {
  value: number[],
  setValue: (value: number[]) => void
}

const Filter = ({setValue, value}: IFilterProps) => {
  return (<SelectChip value={value} setValue={setValue}/>)
}

No compile errors in the same file.

SelectChip

import React, {memo} from "react";

type ValueType = number[] | string[] | number | string

interface ISelectChipProps<X extends ValueType> {
  value: X
  setValue: (value: X) => void
}

const SelectChip = <X extends ValueType>({
  value,
  setValue,
}: ISelectChipProps<X>) => {

  return (
    <></>
  )
}

export default memo(SelectChip)

Filter.tsx

import SelectChip from "@/test/SelectChip";

interface IFilterProps {
  value: number[],
  setValue: (value: number[]) => void
}

const Filter = ({setValue, value}: IFilterProps) => {
  return (<SelectChip value={value} setValue={setValue}/>)
}

An error was reported in the line of code <SelectChip value={value} setValue={setValue}/>:

TS2322: Type '(value: number[]) => void' is not assignable to type '(value: ValueType) => void'. Types of parameters 'value' and 'value' are incompatible.     
Type 'ValueType' is not assignable to type 'number[]'.       
Type 'string' is not assignable to type 'number[]'.  
SelectChip.tsx(7, 3): The expected type comes from property 'setValue' which is declared here on type 'IntrinsicAttributes & ISelectChipProps<ValueType>'

I noticed that IDEA's prompts for these two setValue are different:

// work fine
ISelectChipProps<X>.setValue: (value: number[]) => void
// error
ISelectChipProps<X>.setValue: (value: ValueType) => void

To make sure nothing was missed, I copied the code completely. The environment I'm using is:

"react": "18.2.0"
"typescript": "5.0.4"
"next": "13.3.0"

Can you tell me if my usage is wrong, or is there something wrong with the compiler? If there is a problem with the compiler, how can I locate the problem in one of IDE, TypeScript, React, Next.js?

like image 601
SageJustus Avatar asked Oct 27 '25 22:10

SageJustus


1 Answers

They are not same. When you use them in same file, you just use the SelectChip. But when you use them in saparated files, you use memoized version of SelectChip.

You have:

export default memo(SelectChip)

Sadly, but it removes the generic prop in SelectChip

What you can do is:

export default memo(SelectChip) as typeof SelectChip
like image 143
Oki Avatar answered Oct 30 '25 13:10

Oki