如何在 Typescript 中添加多个断言


我正在尝试下面的代码,不确定是否可以告诉打字稿从任一接口假定类型


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)


我所追求的是让打字稿假设被破坏的变量存在于任一接口中。


当年话下
浏览 93回答 4
4回答

炎炎设计

您的问题是,它cell的类型可能CellA不具有该属性date(因此您收到的错误消息)。请注意,反之亦然,即cell也不具有该属性text。潜在的解决方案1.使用交叉类型如果cell应该是两者的组合CellA,CellB那么你可以制作celltype CellA & CellB。例如:type CellC = CellA & CellBconst cell: CellC = { date: new Date(), text: 'Hello!' }const { date, text }console.log(date, text)2.使用类型守卫:Playground如果您有一个值需要在运行时进行类型检查,则可以使用用户定义的类型保护。例如,如果您有一个cell在运行时不知道其类型的变量:const cell = { text: 'Hello!' } // unknown typefunction 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例如与第三个组件共享公共逻辑。

茅侃侃

您这样做的方式是做出cell同时具有date和text的假设。但是,当您指定cell为 aCellA或CellB类型时,打字稿会抱怨,因为每种类型都缺少其中一个属性。您可以只分配可选属性吗?像这样:interface CellType {&nbsp; date?: Date,&nbsp; text?: string}const { date, text } = cell as CellType或者,如果您确实想强制 acell严格成为这些类型之一,我会在定义变量时执行此操作:interface CellA {&nbsp; text: string;}interface CellB {&nbsp; date: Date;}type CellType = CellA | CellBconst cell: CellType = { ... }

慕村9548890

通常,当您想要在 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;  }}编译器将这种模式理解为您正在根据运行时类型进行分派,但它仍然会提供编译时类型安全性,因为您不能只传递不合格的值。

饮歌长啸

如果可能的话,您可以扩展接口以接受任何其他值。例如:export interface CellA {&nbsp; &nbsp; text?: string;&nbsp; &nbsp; [index: string]: any;}export interface CellB {&nbsp; &nbsp; date?: Date;&nbsp; &nbsp; [index: string]: any;}
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

JavaScript