Typescript is ignoring the type of spreaded object while passing props using spread operator in react + typescript?

huangapple go评论66阅读模式
英文:

Typescript is ignoring the type of spreaded object while passing props using spread operator in react + typescript?

问题

问题很简单。我有一个具有为props定义的接口的React组件。当我使用展开运算符传递一些未知的属性时,它不会报错。我想要获得该错误。

interface MyProps {
   a: string;
   b: string;
}

const MyComponent: React.FC<MyProps> = (props) => {
   return <></>;
};

const props = { a: "a", b: "b", c: "c" };
// 报错:Type '{ a: string; b: string; c: string; }' 无法分配给类型 'IntrinsicAttributes & MyProps'。
// 属性 'c' 不存在于类型 'IntrinsicAttributes & MyProps'。
const comp1 = <MyComponent a="a" b="b" c="3"></MyComponent>;
// 不报错,但应该报错,因为 'c' 不是有效的属性
const comp2 = <MyComponent {...props}></MyComponent>;

这里是可运行的代码。我已经检查了两个GitHub问题,但它们没有解决方案。

https://github.com/microsoft/TypeScript/issues/22144

https://github.com/microsoft/TypeScript/issues/18801

英文:

The issue is simple. I have react component which has an interface define for props. When I am passing some unknown property using the spread operator it is not giving error. I want to get that error.

interface MyProps {
a: string;
b: string;
}

const MyComponent: React.FC<MyProps> = (props) => {
return <></>;
};

const props = { a: &quot;a&quot;, b: &quot;b&quot;, c: &quot;c&quot; };
//Giving error be Type &#39;{ a: string; b: string; c: string; }&#39; is not assignable to type &#39;IntrinsicAttributes &amp; MyProps&#39;.
// Property &#39;c&#39; does not exist on type &#39;IntrinsicAttributes &amp; MyProps
const comp1 = &lt;MyComponent a=&quot;a&quot; b=&quot;b&quot; c=&quot;3&quot;&gt;&lt;/MyComponent&gt;;
//Not giving error while it should because c is not the valid prop
const comp2 = &lt;MyComponent {...props}&gt;&lt;/MyComponent&gt;;

Here is the runnable code. I have checked two github issues but they got no solution.

https://github.com/microsoft/TypeScript/issues/22144

https://github.com/microsoft/TypeScript/issues/18801

答案1

得分: 1

根据我所了解,这是按设计的方式,除非您还使用一些寻找此类问题的代码检查工具(如eslint或sonarlint) ,否则不会出现该错误。

如果这满足您的需求,那么您可以查看eslint插件,名称为eslint-plugin-unicorn,特别是规则名为no-unused-properties。也许这会有所帮助。这是规则的链接:https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/no-unused-properties.md#disallow-unused-object-properties(我没有测试过,所以不能保证它能解决问题,只是一个值得研究的想法)。

如果您担心子组件可以访问不应访问的属性,那么我建议立即在子组件中解构props,以便在那里没有props对象(尽管从技术上讲,props对象将包含c属性,但typescript不允许您访问它[因此props.c是不可能的],除非试图规避它)。

例如,不是

const MyComponent: React.FC<MyProps> = (props) => { return <></>; };

而是

const MyComponent: React.FC<MyProps> = ({a, b}) => { return <></>; };

这样,当使用这种方法时,MyComponent将不再可以访问父级传递的任何额外属性。

<MyComponent {...props}></MyComponent>

因为没有props对象可以访问这些额外的属性。 TypeScript类型检查也不允许您在MyComponent中解构比MyProps接口中定义的更多的props(同样,除非积极尝试规避它)。

不知道这是否解决了您的问题,但这是我解决问题的方法,希望能有所帮助。

英文:

As far as I know this is by design and you won't get that error unless you also use some linting tool that looks for things like this (tools like eslint or sonarlint).

If that satisfies then you look into eslint plugin called eslint-plugin-unicorn and specifically into the rule named no-unused-properties. Maybe that will help. Here is the link to the rule: https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/no-unused-properties.md#disallow-unused-object-properties (I didn't test it, so no guarantees it solves the problem - just an idea to look into)

If you are concerned with the child component having access to properties that it shouldn't have access to, then I would recommend just immediately destructure the props in the child component so there is no props object there (albeit even though technically the props object would have contained the c property, typescript wouldn't allow you to access it [so props.c wouldn't be possible] without trying to get around it).

For example, instead of

const MyComponent: React.FC&lt;MyProps&gt; = (props) =&gt; { return &lt;&gt;&lt;/&gt;; };

You would have

const MyComponent: React.FC&lt;MyProps&gt; = ({a, b}) =&gt; { return &lt;&gt;&lt;/&gt;; };

This way MyComponent won't have access to any additional properties passed by the parent when using this approach.

&lt;MyComponent {...props}&gt;&lt;/MyComponent&gt;

Because there is no more props object to be accessed that would hold these additional properties. Typescript type checking also won't allow you to destructure any more props in the MyComponent than are defined in MyProps interface (again, without actively trying to get around it).

Don't know if that solves your problem, but this is how I get around it, so I hope it helps.

huangapple
  • 本文由 发表于 2023年3月12日 18:21:10
  • 转载请务必保留本文链接:https://go.coder-hub.com/75712462.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定