React Component 精确的 TypeScript Prop 类型

React Component Exact TypeScript Prop Types

当我有这个时:

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

为什么这有效:

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

但这并没有(将值从变量移到此处):

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

此外,当我删除用户的所有已知属性时,它不再起作用:

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

我想知道为什么会这样。为什么它接受“随机”道具,当它处于变量状态时,他不知道。为什么变量类型与直接传递 prop 有不同的行为?有没有办法只允许精确的道具而不每次都给变量类型?

这与 Typescript 的 Excess 属性 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.

您可以在 this link 阅读更多内容。

案例 1 - 结构类型系统

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

在这种情况下,user 的类型被推断为:

{
  random: number;
  name: string;
}

此类型与 PropTypes 兼容,因此没有错误。

案例 2 - 超额 属性 检查

在赋值中传递对象文字:

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

在这种情况下,random 不是类型 PropTypes 的有效 属性,因此打字稿告诉您添加 random 是错误的。

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

案例 3 - 弱类型

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

在这种情况下,typescript 将用户类型推断为:

{
  random: number;
}

同样在这种情况下 random 对于 PropTypes 是无效的 属性,所以这是一个错误。