有没有可能定义一个类型,除了少数指定的字符串值之外,它可以赋值给每个字符串值?我想沿着这个(非编译)例子的思路表达一些东西:
type ReservedNames = "this" | "that"
type FooName = string - ReservedNames;
const f1 : FooName = "This" // Works
const f2 : FooName = "this" // Should error
有没有可能定义一个类型,除了少数指定的字符串值之外,它可以赋值给每个字符串值?我想沿着这个(非编译)例子的思路表达一些东西:
type ReservedNames = "this" | "that"
type FooName = string - ReservedNames;
const f1 : FooName = "This" // Works
const f2 : FooName = "this" // Should error
4条答案
按热度按时间628mspwn1#
对于这个问题没有一个通用的解决方案,因为在类型脚本类型系统中没有办法表达字符串可以是除了列表之外的任何值的事实。(人们可能认为条件类型
Exclude<string, ReservedNames>
可以工作,但它不工作,它只是返回到字符串)。作为一种解决方案,如果我们有一个函数,并且我们特别希望不允许某些常量传入,我们可以使用一个条件类型来检查
ReservedNames
,如果传入的参数是ReservedNames
,那么输入参数的方式实际上是不可能满足的(使用交集类型)。Playground
6l7fqoea2#
这在TypeScript中目前是不可能的,但是如果你添加具体的字符串值作为
FooName
的参数,你可以创建一个可以处理许多实际用例的泛型类型。在一个函数中,如果你让函数在字符串值上泛型化,它会像预期的那样工作:
busg9geu3#
警告:
我希望这是一些react组件,我想采取一些字符串值的prop键,应该是任何东西,而不是一组本地化系统查找常量,而accepted answer from ccarton above做的技巧(在这里也适用:Playgrounds),同样值得一提的是,当你的代码不满足类型约束时,typescript的错误消息是 * 完全垃圾 *,并且具有积极的误导性-来自下面的playground链接/代码的示例:
将鼠标悬停在标记为非法的
title
属性的波浪线上(是的,不是text
),您当前(* 使用typescript 4.7.2,以防它在某些方面有所改进)可以看到:因此,虽然这种方法对于防止提交钩子提交错误代码等事情非常出色,但它依赖于开发人员对这些错误发生时的错误有部落知识,因为错误消息完全脱离了轨道。
完整的示例代码,以防Playgrounds死亡:
qlvxas9a4#
我用以下方法解决了这个问题,其中:
1.创建一个键为
Literals
的对象,Literals
是文字的并集。1.从对象中省略
ExcludedLiterals
类型(Literals
的子集)中的任何文本。1.返回对象的
keyof
分辨率。有点复杂,但很有效。