TypeScript:将字符串字面量类型映射为大写

17
type a = 'one' | 'two'

我想要一个像类型 b这样的东西

type b = 'ONE' | 'TWO'

所以我尝试了

type a = 'one' | 'two'
type b = {[P in a]: P['toUpperCase']}

但那并不做我想要它做的事情。

谢谢阅读 :)


3
如果这是可能的,我会非常印象深刻。但我怀疑可能不行。 - VLAZ
5
类型系统中没有字符串操作。 - Titian Cernicova-Dragomir
我能想到的唯一解决方案是将此type a ='one' | 'two'存储在单独的文件中,然后读取文件内容,并以编程方式将值更改为大写。 - user11534547
3
我猜它能工作,但看起来有点丑陋。你可能可以通过某种构建步骤来转换类型,例如使用 lowercase.d.ts 中的所有内容生成一个 uppercase.d.ts,其中所有字符串字面量类型都是大写的。但是我不确定我真的喜欢这个方法。如果你需要将首字母大写或其他偏离标准的命名约定,那么这种方法似乎很容易让人陷入困境。 - VLAZ
2个回答

28
现在,有了模板字面类型的引入,您可以这样做:UpperCaseStringType
type A = 'one' | 'two'
type B = Uppercase<A>

let b: B = 'one' // Type '"one"' is not assignable to type '"ONE" | "TWO"'.

TS Playground

除了 Uppercase<StringType> 之外,还有以下帮助类型:

  • Lowercase
  • Capitalize
  • Uncapitalize

它们可以在模板字面量类型中使用,如下所示:

type Fruit = 'Apple' | 'Banana'
type FruitField = `fr_${Uncapitalize<Fruit>}`

const fruit: Record<FruitField, boolean> = {
    'fr_apple': true,
    'fr_banana': false,
    'fr_Apple': true, // error
    'fr_peach': false // error
}

TS Playground


2
语法在v4.1.0 beta中略有改变,现在是{大写字母A} - Andrew Shepherd
3
使用v4.2版本后,它已经切换回OP最初编写的方式。 - Geoff Davids

5

这里是链接到 TS Playground

以下是代码:

type A = 'one' | 'two'
type B = Uppercase<A>

let b: B = 'one' // Error

附言:我不理解为什么在之前的评论中,使用一种更复杂的形式来表达相同的意思。

编辑: Derek Nguyen(最佳答案)现在已经用更新且更简单的解决方案更改了他的答案。


1
感谢您指出这一点,如果我没记错,在4.1测试版期间,操作类型(大写<>, 小写<>, 等等)只能在模板文字内起作用。 - Derek Nguyen

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接