Search code examples
reactjstypescriptjsxlinter

Why does typescript break in components with spread?


Why does typescript break if you send props to a component with a spread statement?

Example code

type SomeComponentProps = Readonly<{
  someTitle: string
}>

const SomeComponent = ({ someTitle }: SomeComponentProps) => {
  return <>someTitle</>
}

const MainComponent = () => {
  const someTitle = 'Some title'
  const TICK = 'TICK'

  return <SomeComponent {...{ someTitle, TICK }} />
}

link codesandbox

TICK is not underlined in red and the linter will not pick up the error


Solution

  • This is a behaviour present with TS without React too.

    Take the below example:

    const split = { a : 1 , b : 2};
    const func = ({a } :{ a : number}) => {
        console.log(a);
    };
    func(split)
    

    TS will not complain about the above. You might be passing extra keys into the object, but as long as you are passing the mandatory keys it works.

    Take this example now:

    const split3 = { a : 1 };
    const split2 = { x : 1};
    const func2 = ({x ,a} :{ x : number, a: number}) => {
        console.log(x);
    };
    
    func2(split)
    func2(split2)
    

    Both the above statements will be errored out by TS as both x and a are not provided and only one of them is.

    Demo

    props is also one of the arugments passed the functional component, and it will not error out when extra keys are passed into any of its object. The extra properties of an object are not checked in most cases.

    Note: Excess properties are still checked when you are assigning object literal. Below will throw an error:

    interface test{ 
        a: number;
    }
    
    let x : test = {
        a: 1,
        b: 2,
    }