簡體   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