【问题标题】:Typescript, conditional type based on the value of a string literal typeTypescript,基于字符串文字类型值的条件类型
【发布时间】:2018-05-29 17:16:27
【问题描述】:

我有点纠结于如何根据预定义的字符串文字为打字稿定义条件类型

这是一个帮助解释的模型/示例对于一些背景知识,用户应该从图像中标记数据,目前只有 2 种类型的东西要标记(对于这个例子,让我们说它的pedestriansvehicles) 未来可能会更多。

在我的 Redux 存储中,我存储来自 API 请求的数据(请求获取一组新数据以根据其中一种类型进行标记)。问题是我得到的数据格式不同,这两种类型的东西用帧数组的值来标记又名帧数组或对象。

type ILabelingTypes = "pedestrians" | "vehicles"

框架看起来像这样

interface IFrame {
    url: string
    orientation: number
    // anything else related to a frame
}

API 请求将是 /labeling/vehicles/new 并带有示例响应

{
    // meta info about the labeling session
    frames: IFrame[]
}

/labeling/pedestrians/new 提供示例响应

{
    // meta info about the labeling session
    frames: Map<string, IFrame[]>
}

我现在遇到的问题是,当我定义我的商店界面时,我如何正确键入frames 键,这样我就不必到处检查使用它的数据类型是什么?

interface ILabelingStore {
    labelingType: ILabelingTypes
    frames: // what do i put here?
}

当我去渲染或使用这些数据时,我想简单地调用我知道存在的方法,具体取决于商店中定义的labelingType


对于 React 组件方面,当我去渲染帧时,我会构建一个帧队列来完成,所以我需要知道相应组件中的数据是什么类型 (这就是我想要的而不必检查框架的类型)

// pedestrians component
componentDidMount() {
    Object.entries(this.props.frames).forEach( (key, val) => this.queue.concat(val))
}

// vehicles component
componentDidMount() {
    this.queue.concat(this.props.frames)
}

【问题讨论】:

    标签: reactjs typescript redux


    【解决方案1】:

    你可以创建一个有区别的联合:

    type ILabelingStore = ({
            labelingType: "vehicles",
            frames: IFrame[]
        } | {
            labelingType: "pedestrians",
            frames: { [key: string]: IFrame[] }
        });
    

    Demo

    【讨论】:

    • 感谢您的快速回复!这看起来像我需要的,但我的 redux 存储中有一些编译器错误(返回值不匹配)。解决这些问题后,如果这解决了我的问题,我会接受! :)
    • 我在将字符串文字类型分配给可区分联合时遇到问题。介意看看吗? preview.tinyurl.com/y8ougmxv
    • 编译器无法证明payload与你的对象的值相同,所以它给你一个错误,因为它害怕属性不再匹配。
    • 那么我将如何证明这一点?我已经指定payload 是这些值之一。我需要做一个类型后卫吗?我尝试了没有运气的类型保护:/
    • 我认为您需要使您的 lambda 通用,以便您可以指定类型系统中的 ILabelingTypes。然后它将只接受与其类型参数匹配的任何参数。
    猜你喜欢
    • 2021-06-23
    • 1970-01-01
    • 2019-11-06
    • 1970-01-01
    • 2018-05-18
    • 1970-01-01
    • 1970-01-01
    • 2017-02-03
    • 2017-03-31
    相关资源
    最近更新 更多