題
我有一個減速器模型,其動作接受payload期望的{ id: string, newValues: Partial<A_or_B> }. 在下面的代碼中,A_or_B當我宣告newValuesinline時,不會強制執行型別;但是,如果我newValues提前宣告并為其分配屬性,則會強制執行約束。即使宣告為行內,我如何強制執行約束?A_or_BnewValues
有問題的代碼
import { useContext } from "react";
import { AppDispatchContext } from "../src/AppProvider";
import { ActionTypes, A_or_B } from "./interfaces";
export default function App() {
const dispatch = useContext(AppDispatchContext);
const x: Partial<A_or_B> = {};
// Property 'color' does not exist on type
// 'Partial<A> | Partial<B>'.
// Property 'color' does not exist on type 'Partial<A>'.
x.color = "red";
dispatch({
type: ActionTypes.POINT_UPDATED,
// why can I assign a color to Partial<A>|Partial<B> if 'color'
// only exists on B?
payload: { id: "x", newValues: { color: "red" } }
});
}
代碼沙盒鏈接
CodeSandbox 鏈接在這里
uj5u.com熱心網友回復:
這些約束實際上是在您的有效負載中強制執行的。您可以通過在型別 A 或 B 上不存在的負載上添加屬性來驗證這一點。
這里真正的問題是型別推斷。
const x: Partial<A_or_B> = {};
// Property 'color' does not exist on type
// 'Partial<A> | Partial<B>'.
// Property 'color' does not exist on type 'Partial<A>'.
x.color = "red";
x被分配了一個有效的聯合值,但 Typescript 無法判斷它是 A 型還是 B 型,因此x.color無法驗證,因為 TS 認為它有可能是 B 型。
payload: { id: "x", newValues: { color: "red" } }
newValues被顯式設定為一個僅包含的物件,color這意味著 Typescript 知道這必須是 A 型別。
例子
uj5u.com熱心網友回復:
這是大多數人union在打字稿中遇到型別的常見問題。有些人將它們視為交叉型別,而有些人希望它們的行為更像互斥型別。
但是,打字稿對聯合型別有兩種不同的解釋,具體取決于您的用例。
特性
當您嘗試訪問的聯合型別的屬性,你只能訪問屬性是普通工會的所有成員之間。另一種說法是,您只能訪問聯合成員的屬性的交集。
這可能是一口,但打字稿檔案給出了一個很好的類比來解釋這一點:
例如,如果我們有一個房間的高個子戴帽子,另一個房間說西班牙語的人戴帽子,將這些房間合并后,我們唯一知道的關于每個人的資訊就是他們必須戴帽子。
所以在屬性訪問的情況下,typescript 只允許訪問屬性的一個子集(沒有來自用戶的任何進一步提示),從而形成一個交集。
成員資格(又名型別推斷)
在型別推斷方面,編譯器在允許匹配聯合型別方面非常自由。從本質上講,如果你想成為這個團體的一員,你只需要看起來像這個團體的成員之一。在這種情況下,您不必擁有與聯合的每個成員的屬性相匹配的屬性。
也許您的問題的解決方案是只使用交集型別x:
const x: Partial<A&B> = {};
x.color = "red"; // works!
...
newValues: x; // also works
這解決了屬性訪問和成員資格的問題
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/311194.html
上一篇:如何解決IntelliJ突出顯示的未經檢查的強制轉換問題?
下一篇:Gorm查找結果到介面
