【问题标题】:Union type as key in interface?联合类型作为界面中的键?
【发布时间】:2019-07-28 03:33:39
【问题描述】:

是否可以使用联合类型作为接口中的键?例如,我想做这样的事情:

interface IMargin {
  [key in 'foo' | 'bar']: boolean;
}

但我收到此错误:

接口中的计算属性名称必须引用类型为文字类型或“唯一符号”类型的表达式。ts(1169)

有没有办法解决这个问题?

用例是将值数组转换为接口:

const possibleTypes = ['foo', 'bar'];
interface Types {
    foo?: boolean;
    bar?: boolean;
}

【问题讨论】:

  • 可能是keyof Types?

标签: typescript


【解决方案1】:

您可以使用对象类型而不是接口,它们大多是可互换的:

type IMargin = {
    [key in 'foo' | 'bar']: boolean;
}

【讨论】:

  • 这很有帮助,谢谢——采用 type 而不是 interface 让我在其中有所作为。正如您在我对 Titian 回答的评论中看到的那样,我仍然无法从数组中生成联合类型。
  • 我收到A computed property name in an interface must refer to an expression whose type is a literal type or a 'unique symbol' type.ts(1169)
【解决方案2】:

这不一定是答案,但我认为这可能会让其他人感兴趣。

您可以使用联合类型作为接口的子属性中的键

export type Language = 'EN' | 'DE' | 'IT';

export interface Document {
  generic: string;
  languages: {
    [key in Language]: string[];
  }
}

【讨论】:

  • 它被视为使用type 关键字。如果您使用type 而不是interface,您也可以在那里进行操作。
【解决方案3】:

接口不支持映射类型(这是您在这里寻找的)。您可以使用类型别名,在大多数情况下,它的工作方式应该相同(并非所有情况,但如果类型已知,您可以像实现接口一样实现类型别名)。

const possibleTypes = (<T extends string[]>(...o: T) => o)('foo', 'bar');
type Types = Record<typeof possibleTypes[number], boolean>

映射类型Record 应该在这里工作

【讨论】:

  • 您好,谢谢您的回答。只要您直接传入('foo', 'bar'),就可以了。但是,当你传入(...['foo', 'bar']) 时它不起作用。有没有什么办法解决这一问题?这里的用例是从数组生成类型或接口。
  • @ElliotBonneville 你是指possibleTypes 中的IIFE?这个想法是该数组应该是一个字面量类型,可以键入为元组['foo', 'bar'] 或数组Array&lt;'foo' | 'bar'&gt;。如果您正确键入了该数组,则可以在没有 IIFE 的情况下使用它。否则,您要么需要将其断言为上述类型之一。如果只是使用数组的语法偏好,您可以使用const possibleTypes = (&lt;T extends string&gt;(o: T[]) =&gt; o)(['foo', 'bar']);,但我更喜欢原始版本:)
  • @ElliotBonneville (...['foo', 'bar']) 不起作用,这是 ts 的限制。在展开操作之前,数组文字将被推断为string[],因此文字类型会丢失
  • 啊,我明白了。这有助于更多,我们正在到达那里!尽管将其拉入我的实际用例,但我仍然陷入困境。我有一种感觉,字符串文字类型在某处的翻译中丢失了。这是我要完成的工作:stackblitz.com/edit/typescript-dftj9c
  • @ElliotBonneville 是一匹不同颜色的马。不幸的是,您无法从连接中创建字符串文字类型。无论如何,您的类型都会丢失,因为参数是 string[] 的类型,可以使用泛型解决。但是你目前在类型系统中仍然无法生成prefix1_a作为字符串字面量类型。
猜你喜欢
  • 2020-04-02
  • 2021-02-05
  • 2023-03-17
  • 2021-08-17
  • 2021-12-02
  • 1970-01-01
  • 1970-01-01
  • 2020-02-08
  • 2019-06-28
相关资源
最近更新 更多