如何在接口中使用字符串枚举类型作为计算的属性名称?

Shepmaster

我在TypeScript中建模API请求格式:

interface ApiTerm {
    term: {
        name: string,
        value: string,
    }
}

interface ApiAnd {
    and: {
        lhs: ApiItem,
        rhs: ApiItem,
    }
}

interface ApiOr {
    or: {
        lhs: ApiItem,
        rhs: ApiItem,
    }
}

type ApiItem =
    | ApiTerm
    | ApiAnd
    | ApiOr
    ;

这行得通,但是我将需要实现除“ and”和“ or”之外的许多二进制操作,因此我想以某种方式来缩短和重用代码。

在我编写了一些在接口中使用特定字符串枚举值的其他代码之后,我尝试使用字符串枚举作为属性名称:

enum Operation {
    And = "and",
    Or = "or",
}

interface ApiBinary<O extends Operation> {
    [O]: {
        lhs: ApiItem,
        rhs: ApiItem,
    }
}

type ApiItem =
    | ApiTerm
    | ApiBinary<Operation.And>
    | ApiBinary<Operation.Or>
    ;

不幸的是,这会产生TypeScript 2.9.1错误:

A computed property name in an interface must refer to an expression whose type is a literal type or a 'unique symbol' type.

有没有一种替代解决方案,可以使我避免写出仅键名不同的大量重复接口?

查看错误消息的“唯一符号”类型,我不相信可以基于Symbols创建枚举

相关问题

在TypeScript界面​​中使用字符串枚举值作为计算的属性键似乎非常接近,但是它涉及在接口中使用特定的字符串枚举值,该接口在较新的TypeScript版本中可以直接使用。

蒿甲醚

除了使用计算属性之外,还可以使用映射类型:

interface ApiTerm {
    term: {
        name: string,
        value: string,
    }
}

enum Operation {
    And = "and",
    Or = "or",
}

type ApiBinary<O extends Operation> = {[o in O]: {
        lhs: ApiItem,
        rhs: ApiItem,
    }
}

type ApiItem =
    | ApiTerm
    | ApiBinary<Operation.And>
    | ApiBinary<Operation.Or>
    ;

const andExample: ApiBinary<Operation.And> = {
    'and': {
        lhs: { term: { name: 'a', value: 'b' } },
        rhs: { term: { name: 'c', value: 'd' } }
    }
}

但是,请注意,没有办法表达ApiBinary只能具有一个属性的限制例如,有人可以声明type N = ApiBinary<Operation.And | Operation.Or>;

当使用映射类型时,它不能与计算属性很好地混合-ApiItem在此示例中,编译器无法推断计算属性类型符合约束

const foo = ({ kind, lhs, rhs }: { kind: Operation, lhs: ApiItem, rhs: ApiItem }): ApiItem =>
({ [kind]: { lhs, rhs } });

该错误is not assignable to type 'ApiBinary<Operation.Or>'之所以存在,是因为编译器尝试检查对所有联合成员的可分配性,如果失败,则仅告知最后一个。

我认为编写此函数的唯一方法是冗长的:

const foo = <O extends Operation>({ kind, lhs, rhs }: { kind: O, lhs: ApiItem, rhs: ApiItem }) => {
    const result = {} as ApiBinary<O>;
    result[kind] = {lhs, rhs};
    return result;
}

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

如何在Golang中使用字符串作为rand.Seed()函数的输入?

如何在Vue Js中使用字符串变量模式创建输入名称字段?

如何在FluentProvider for Vapor中使用字符串化的UUID作为主键-Swift

在C#中使用字符串作为类属性的名称

如何在函数中使用字符串作为变量名?

如何在F#中使用字符串类型列表的auto属性声明类?

如何在Flow中使用通用字符串扩展Error接口?

在React中如何在setState调用中使用字符串作为键

在Typescript中,如何在接口中使用字符串文字类型?

如何在图表中使用字符串值作为X轴而不是双精度?

如何在dplyr中使用字符串变量作为过滤条件

如何使用字符串的值作为对象的名称?

如何使用字符串数组作为接口的键?

使用字符串作为属性名称

PHP:如何在文件输出中使用字符串生成索引名称?

如何在Android中使用字符串名称调用资源?

如何在python中使用字符串作为数组的名称,以便可以在for循环中使用

如何在json数据中使用字符串作为选择器?

在视图中使用字符串作为范围属性名称的角度

我可以在 Visual Basic 中使用字符串作为名称来更改对象属性吗?

如何使用字符串作为 SKScene 的名称

如何在 JAVA 中使用字符串变量作为对象名称?

如何在php中使用字符串作为数学计算公式?

我如何在 switch case 中使用字符串作为动作?

如何在熊猫数据框中使用字符串作为列名

如何在 Bigquery 中使用字符串作为列名

如何在Typescript中使用字符串变量值作为对象中的键名

如何在 TypeScript 中使用字符串作为数组的键

如何在 for 循环中使用字符串值作为列选择器