Home > database >  React Component Exact TypeScript Prop Types
React Component Exact TypeScript Prop Types

Time:03-28

When I have this:

interface PropTypes {
   user?: {
      name?: string,
      age?: number
   }
}
const Comp = (props: PropTypes) => ...

Why this works:

const user = {
   random: 3,
   name: 'test'
}
<Comp user={user} />  // works

But this does not (moved value from variable to here):

<Comp user={{ random: 3,  name: 'test' }} />   // does not work

Also when I delete all known properties from user it does not work anymore:

const user = {
   random: 3
}
<Comp user={user} />   // does not work

I want to know why it works like this. Why it accepts the "random" prop, that is unknown for him when it is in variable. Why variable type has different behaviour than directly passing prop? Is there any way to allow only exact props without giving type each time to the variable?

CodePudding user response:

This has to do with Typescript's Excess Property Checking.

Structural Type System: TypeScript is fine with having extra properties as long as you provide a type with its’ required properties.

When TypeScript encounters object literal in assignments or when passed as an argument to functions it triggers an action called Excess Property Checking. Contrary to structural typing, it check whether the object has the exact properties.

One interesting behavior is with “Weak Types” — types which all their fields are marked as Optional. In this case the excess property checking an action takes place even when assigning intermediate variable.

You can read more at this link.

Case 1 - Structural Type System

const user = {
   random: 3,
   name: 'test'
}
<Comp user={user} />  // works

In this case the type of user is inferred as:

{
  random: number;
  name: string;
}

This type is compatible with PropTypes, so no error.

Case 2 - Excess Property Checking

Passing object literal in assignments:

<Comp user={{ random: 3,  name: 'test' }} />   // does not work

In this case random is not a valid property for type PropTypes, so typescript tells you adding random is an error.

Object literal may only specify known properties, and 'random' does not exist in type '{ name?: string | undefined; age?: number | undefined; }'

Case 3 - Weak Types

const user = {
   random: 3
}
<Comp user={user} />   // does not work

In this case typescript inferred the type of user as:

{
  random: number;
}

Also in this case random is an invalid property for PropTypes, so this is an error.

  • Related