带有嵌套属性的打字稿判别联盟,有很多可能性清单

发布于 2025-01-30 06:50:23 字数 3394 浏览 2 评论 0原文

我在几个地方读到,目前与嵌套属性有判别的工会是不可行的,或者至少没有防护功能是不可行的,我想知道是否有一种根本不使用后卫功能来确定类型的方法。

目的是尝试使用枚举来缩小缩小,因为多个customfieldtype可以具有相同类型的value,并且每次使用Switch语句每次注册案例都会更简单而不是if-elseif要缩小。

Here is a typescript playground that tries the different possibilities.

enum CustomFieldType {
    INT = 'int',
    STRING = 'string',
    MULTISELECT = 'multiselect',
    SELECT = 'select'
    // Possibly 20 others
}

interface CustomFieldValueBase<T extends CustomFieldType> {
    customField: {
        type: T;
    }
    value: any;
}

interface CustomFieldValueInt extends CustomFieldValueBase<CustomFieldType.INT> {
    value: number;
}
interface CustomFieldValueString extends CustomFieldValueBase<CustomFieldType.STRING> {
    value: string;
}
interface CustomFieldValueMultiSelect extends CustomFieldValueBase<CustomFieldType.MULTISELECT> {
    value: number[];
}
interface CustomFieldValueSelect extends CustomFieldValueBase<CustomFieldType.SELECT> {
    value: number[];
}

type CustomFieldValue =
  | CustomFieldValueInt
  | CustomFieldValueString
  | CustomFieldValueMultiSelect
  | CustomFieldValueSelect


// Solution wanted
// Won't narrow
function guessType(cfv: CustomFieldValue) {
    switch (cfv.customField.type) {
        case CustomFieldType.INT:
            return cfv.value // should be narrowed to number
        case CustomFieldType.STRING:
            return cfv.value // should be narrowed to string
        case CustomFieldType.MULTISELECT:
        case CustomFieldType.SELECT:
            return cfv.value // should be narrowed to number[]
        default: throw new Error()
    }
}

I read at a few places that discriminant unions from a nested property are not something feasible at this moment, or at least not without guard functions and I wanted to know if there's a way not to use guard functions at all to determine a type.

The goal is to try to use Enums for narrowing because multiple CustomFieldType can have the same type of value, and it would be simpler to register cases every time by using a switch statement rather than if-elseif to narrow down.

Here is a typescript playground that tries the different possibilities.

enum CustomFieldType {
    INT = 'int',
    STRING = 'string',
    MULTISELECT = 'multiselect',
    SELECT = 'select'
    // Possibly 20 others
}

interface CustomFieldValueBase<T extends CustomFieldType> {
    customField: {
        type: T;
    }
    value: any;
}

interface CustomFieldValueInt extends CustomFieldValueBase<CustomFieldType.INT> {
    value: number;
}
interface CustomFieldValueString extends CustomFieldValueBase<CustomFieldType.STRING> {
    value: string;
}
interface CustomFieldValueMultiSelect extends CustomFieldValueBase<CustomFieldType.MULTISELECT> {
    value: number[];
}
interface CustomFieldValueSelect extends CustomFieldValueBase<CustomFieldType.SELECT> {
    value: number[];
}

type CustomFieldValue =
  | CustomFieldValueInt
  | CustomFieldValueString
  | CustomFieldValueMultiSelect
  | CustomFieldValueSelect


// Solution wanted
// Won't narrow
function guessType(cfv: CustomFieldValue) {
    switch (cfv.customField.type) {
        case CustomFieldType.INT:
            return cfv.value // should be narrowed to number
        case CustomFieldType.STRING:
            return cfv.value // should be narrowed to string
        case CustomFieldType.MULTISELECT:
        case CustomFieldType.SELECT:
            return cfv.value // should be narrowed to number[]
        default: throw new Error()
    }
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文