繁体   English   中英

为什么在导入组件时 typescript 会报错,但在同一文件中定义组件时不会报错?

[英]Why does typescript complain when I import a component, but not when the component is defined in the same file?

我有一个问题,当我从另一个文件导入组件与在使用它的同一文件中定义组件时,我从 Typescript 的类型检查中得到两个不同的结果。

我制作了一个沙箱来更详细地描述问题: https://codesandbox.io/s/typescript-error-1l44t?file=/src/App.tsx

如果您查看Example function,我传递了一个额外的参数z ,它应该是无效的,因此我得到一个错误(如预期的那样)。

但是,如果您启用 L15-L22,其中ExampleComponent在同一文件中定义,然后禁用或删除从 L2 上'./component' ExampleComponent的 ExampleComponent,Typescript 突然停止抱怨。

任何帮助,将不胜感激。 谢谢!

如果我可以提供任何额外的信息,请告诉我。

这是因为您正在精炼 scope 中的类型,但如果您导出该值,您也不会得到这些精炼。

换句话说,当您在同一个文件中创建值时,Typescript 可以推断出更具体的子类型。 但是当它在另一个文件中时,它只会导入它可能是最广泛的类型。

这是一个更简单的例子:

// test.ts
export const test: string | number = 'a string';
test.toUpperCase(); // works

这是有效的,因为 typescript 观察到test是一个字符串,因为分配了一个字符串文字。 在执行该文件的代码之后, test不可能是一个数字。

但是, test仍然输入为string | number string | number 只是在这个 scope typescript 中可以对更窄的类型进行细化。

现在让我们将test导入另一个文件:

// other.ts
import { test } from './test'
test.toUpperCase() // Property 'toFixed' does not exist on type 'string | number'.

改进仅适用于对其进行改进的 scope。 这意味着当您导出该值时,您将获得更广泛的类型。


另一个例子:

// test.ts
export const test = Math.random() > 0.5 ? 'abc' : 123 // string | number
if (typeof test === 'string') throw Error('string not allowed!')
const addition = test + 10 // works fine

// other.ts
import { test } from './test'
const addition = test + 10 // Operator '+' cannot be applied to types 'string | number' and 'number'.(2365)

在这种情况下,如果分配了字符串,程序应该抛出异常。 test.ts文件中,typescript 知道这一点,因此如果第三行正在执行,则知道test必须是一个数字。

但是,导出的类型仍然是string | number string | number ,因为这就是所说的。


在您的代码中, React.ComponentType<P>实际上是以下的别名:

React.ComponentClass<P, any> | React.FunctionComponent<P>

Typescript 注意到您分配的是 function,而不是 class,并将该类型细化为React.FunctionComponent<P> 但是当你从另一个文件导入时,它可能是,所以 typescript 更加偏执,你会得到类型错误。

最后,由于我还没有弄清楚的原因,您的代码适用于 function 组件,但不适用于 class 组件。 但这至少应该清楚为什么会有差异。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM