4 回答

TA貢獻1808條經驗 獲得超4個贊
您的問題是,它cell的類型可能CellA不具有該屬性date(因此您收到的錯誤消息)。請注意,反之亦然,即cell也不具有該屬性text。
潛在的解決方案
1.使用交叉類型
如果cell應該是兩者的組合CellA,CellB那么你可以制作celltype CellA & CellB。例如:
type CellC = CellA & CellB
const cell: CellC = { date: new Date(), text: 'Hello!' }
const { date, text }
console.log(date, text)
2.使用類型守衛:Playground
如果您有一個值需要在運行時進行類型檢查,則可以使用用戶定義的類型保護。例如,如果您有一個cell
在運行時不知道其類型的變量:
const cell = { text: 'Hello!' } // unknown type
function isCellA(obj: any): obj is CellA {
? ? if(!obj) return false
? ? if(!obj.text) return false
? ? if(typeof obj.text !== 'string') return false
? ? return true
}
if(isCellA(cell)) {
? ? // at this point the compiler recognizes that cell
? ? // is of type CellA
? ? console.log(cell.text)
}
如果您需要在運行時進行類型檢查,這可能是您的最佳選擇。它可以維護類型安全,并有助于減少運行時錯誤(如果cell確實不是您所期望的那樣)。
3.擴展另一個接口
這與解決方案#1 非常相似。如果CellA和CellB應該共享一些屬性,那么它們之一可以擴展另一個,或者它們可以擴展一個公共接口。例如:
interface Cell {
? ? date: Date
}
interface CellC extends Cell {
? ? text: string
}
4:React組件組成
如果您特別遇到此問題,React(如您的評論所述),您可以考慮使用一個單獨的組件來返回每種單元格類型的主要組件。例子:
function ACell({ data }: { data: CellA } ) {
? ? return <Cell>{data.text}<Cell>
}
function BCell({ data }: { data: CellB } ) {
? ? return <Cell>{data.date.toString()}<Cell>
}
function Cell({ children }: { children: string }) {
? ? return <p>{children}</p>
}
也許這不符合您的特定用例,但類似的東西可能有助于分離組件之間每種類型單元的邏輯,以及Cell例如與第三個組件共享公共邏輯。

TA貢獻1842條經驗 獲得超21個贊
您這樣做的方式是做出cell同時具有date和text的假設。但是,當您指定cell為 aCellA或CellB類型時,打字稿會抱怨,因為每種類型都缺少其中一個屬性。
您可以只分配可選屬性嗎?像這樣:
interface CellType {
date?: Date,
text?: string
}
const { date, text } = cell as CellType
或者,如果您確實想強制 acell嚴格成為這些類型之一,我會在定義變量時執行此操作:
interface CellA {
text: string;
}
interface CellB {
date: Date;
}
type CellType = CellA | CellB
const cell: CellType = { ... }

TA貢獻1884條經驗 獲得超4個贊
通常,當您想要在 Typescript 中的參數/變量類型上切換控制流時,您需要使用可區分聯合:
interface CellA {
? text: string,
? kind: "CellA",
}
interface CellB {
? date: Date,
? kind: "CellB",
}
type Cell = CellA | CellB;
function takesACell(cell: Cell) {
? switch(cell.kind) {
? ? case "CellA":
? ? ? console.log("Got an A");
? ? ? cell.text; // no type error
? ? ? break;
? ? case "CellB":
? ? ? console.log("Got a B");
? ? ? cell.date; // no type error
? ? ? break;
? }
}
編譯器將這種模式理解為您正在根據運行時類型進行分派,但它仍然會提供編譯時類型安全性,因為您不能只傳遞不合格的值。

TA貢獻1951條經驗 獲得超3個贊
如果可能的話,您可以擴展接口以接受任何其他值。例如:
export interface CellA {
text?: string;
[index: string]: any;
}
export interface CellB {
date?: Date;
[index: string]: any;
}
添加回答
舉報