【问题标题】:TypeScript types based on capitalization of a key基于键大小写的 TypeScript 类型
【发布时间】:2021-09-10 21:19:44
【问题描述】:

尝试将类型添加到我正在使用的现有 JS 库中。不幸的是,该库有一条规则,即对象中值的类型在某种程度上取决于其关联键的第一个字母的大小写。我认为像下面这样的东西可能会起作用,但它不起作用。

type UppercaseLetters = 'A' | 'B' | 'C' | 'D' | 'E' | 'F' | 'G' | 'H' | 'I' | 'J' | 'K' | 'L' | 'M' | 'N' | 'O' | 'P' | 'Q' | 'R' | 'S' | 'T' | 'U' | 'V' | 'W' | 'X' | 'Y' | 'Z';
type LowercaseLetters = Lowercase<UppercaseLetters>;

type RefKey = `${UppercaseLetters}${string}`
type PropKey = `${LowercaseLetters}${string}`

// Define these types just so it compiles
type SomeRefType = number;
type SomePropType = boolean;

type Spec = {
  type: string
} & {
  [s in RefKey]: SomeRefType
} & {
  [s in PropKey]: SomePropType
};

这样可以编译,但是Spec变成的实际类型是:

type Spec = {
    type: string;
} & {} & {}

有什么想法吗?也许这种情况对 TypeScript 来说太离谱了。

示例对象:

const specObj: Spec = {
  type: 'Some string',
  Apple: 3,
  Orange: 6,
  lowerCaseKey: false,
  anotherOne: true
}

【问题讨论】:

  • 当它被包含在一个版本中时,它应该由this PR 修复。与此同时,我没有看到任何解决您的问题的方法。
  • 但是,在playground 中尝试,您的type 属性和t${string} 之间仍然存在冲突
  • 哎呀!是的一个错字。我的思绪不知何故退回到 C
  • @FrankWeindel - 嗯,发生了。只是问你,因为迟早人们会开始打扰你:) 至于问题,是的,你必须等到它上线,你现在无能为力。
  • @FrankWeindel - 顺便说一句,RefKeyPropKey 的实际容量是否有限?我的意思是,它们拥有任意属性还是一组固定的属性?

标签: typescript template-literals mapped-types


【解决方案1】:

正如 cmets 中 Alateros 所指出的,由于 typescript@4.4 您可以使用 index signatures for template literals

尽管您仍然必须确保type 字段必须是必需的,并且可能具有与lowercased 键类型不兼容的类型。所以你可以这样写Spec

type Spec = {
  [K in RefKey | PropKey]: 'type' extends K 
      ? string 
      : K extends RefKey 
          ? SomeRefType 
          : K extends PropKey 
              ? SomePropType
              : never
} & {
  type: string
}

playground link

【讨论】:

  • 现在随着 TS 4.4 的发布重新审视这一点。希望它不那么复杂,但它有效!感谢您的帮助!
【解决方案2】:

我删除了

type RefKey = `${UppercaseLetters}${string}`
type PropKey = `${LowercaseLetters}${string}`

并替换为UppercaseLettersLowercaseLetters 类型

你在找什么?

【讨论】:

  • 对不起,没有。我正在尝试根据键的第一个字母的大小写来应用类型。
  • 我刚刚看到了结果示例(输出)。你能展示一下你会得到的输入/类型吗?
  • 不确定我理解你的意思。我发布的示例是输入和输出。我正在尝试让 TypeScript 将其视为有效对象。
猜你喜欢
  • 1970-01-01
  • 2017-09-26
  • 2019-04-03
  • 1970-01-01
  • 2021-03-26
  • 2017-05-12
  • 1970-01-01
  • 1970-01-01
  • 2021-07-21
相关资源
最近更新 更多