我有以下两个接口:

    export interface IQuestion {
        type: 'single' | 'sort'
        prompt: string;
        options: {
            id: string,
            text: string
        }[]
    }
    export type ICurrentQuestion  = {
        correctAnswerId: string | string[],
        question: IQuestion, 
        extraData?: IResultsAnswerData
    }

如果问题类型是sort,那么correctAnswerId就是string[].我不想将类型移动到顶层,因为问题是发送给客户端的内容,所以我必须在两个级别上复制类型.从我的研究来看,我想做的似乎是不可能的,但我很难把我的头包装在这里的类型安全的最佳方式是什么.

首先,感谢那些聪明的人!:)

推荐答案

如果你想要一个类型是this或that,那么你应该把它设为union type.

其中一个类型的correctAnswerIdstringquestion.type属性为"single":

interface SingleCurrentQuestion {
   correctAnswerId: string,
   question: SingleQuestion,
   extraData?: IResultsAnswerData
}
interface SingleQuestion {
   type: 'single'
   prompt: string;
   options: {
      id: string,
      text: string
   }[]
}

另一个是correctAnswerIdstring[]question.type"sort"属性:

interface SortCurrentQuestion {
   correctAnswerId: string[],
   question: SortQuestion,
   extraData?: IResultsAnswerData
}    
interface SortQuestion {
   type: 'sort'
   prompt: string;
   options: {
      id: string,
      text: string
   }[]
}

所以你想要的类型是这些的结合:

type CurrentQuestion =
   SortCurrentQuestion | SingleCurrentQuestion;

请注意,因为它是一个联合,它不能直接是interface,只能是type alias.但这对大多数用例来说并不重要.

另外,请注意,由于"sort" vs "single"属性嵌套在question属性中,CurrentQuestion是一个union,但notdiscriminated union,所以你不能写if (q.question.type === "single") { ⋯ } else { ⋯ },而期望q被缩小到这些块中. 在microsoft/TypeScript#18758处有一个长期存在的开放特性请求来支持这种嵌套判别式,但目前它还不是语言的一部分.

Playground link to code

Typescript相关问答推荐

如何使用TypScript和react-hook-form在Next.js 14中创建通用表单组件?

如何在类型脚本中声明对象其键名称不同但类型相同?

在TypScript手册中可以视为接口类型是什么意思?

Angular 过滤器形式基于某些条件的数组控制

动态判断TypScript对象是否具有不带自定义类型保护的键

如何将类型从变量参数转换为返回中的不同形状?

为什么T[数字]不也返回UNDEFINED?

如果字符串文字类型是泛型类型,则用反引号将该类型括起来会中断

有条件地删除区分的联合类型中的属性的可选属性

Angular文件上传到Spring Boot失败,多部分边界拒绝

保护函数调用,以便深度嵌套的对象具有必须与同级属性函数cargument的类型匹配的键

使用TypeScrip的类型继承

正确使用相交类型的打字集

刷新时保持当前名称的Angular

Typescript 类型守卫一个类泛型?

使用泛型识别对象值类型

为什么TypeScrip不能解析对象析构中的赋值?

使用 fp-ts 时如何使用 TypeScript 序列化任务执行?

如何在由函数参数推断的记录类型中具有多个对象字段类型

TS 条件类型无法识别条件参数