亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

如何在 Typescript 中添加多個斷言

如何在 Typescript 中添加多個斷言

當年話下 2023-07-06 17:01:03
我正在嘗試下面的代碼,不確定是否可以告訴打字稿從任一接口假定類型export interface CellA {? ? text: string;}export interface CellB {? ? date: Date;}var cell = {};const { date, text } = cell as (CellA | CellB);console.log(date, text);TS 錯誤:類型“CellA | ”上不存在屬性“日期” 細胞B'。(2339)我所追求的是讓打字稿假設被破壞的變量存在于任一接口中。
查看完整描述

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例如與第三個組件共享公共邏輯。


查看完整回答
反對 回復 2023-07-06
?
茅侃侃

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 = { ... }


查看完整回答
反對 回復 2023-07-06
?
慕村9548890

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;

? }

}

編譯器將這種模式理解為您正在根據運行時類型進行分派,但它仍然會提供編譯時類型安全性,因為您不能只傳遞不合格的值。


查看完整回答
反對 回復 2023-07-06
?
飲歌長嘯

TA貢獻1951條經驗 獲得超3個贊

如果可能的話,您可以擴展接口以接受任何其他值。例如:


export interface CellA {

    text?: string;

    [index: string]: any;

}


export interface CellB {

    date?: Date;

    [index: string]: any;

}


查看完整回答
反對 回復 2023-07-06
  • 4 回答
  • 0 關注
  • 151 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號