TypeScript递归条件映射类型

TypeScript递归条件映射类型,typescript,Typescript,我需要使用一个或多个测试函数测试多个HTMLInputElements的每个值,并自动为每个值生成一个复选框嵌套列表,条件表示为conditions,如下所示: type TestFunction = (value: string) => boolean type TestFunctionObject = { [description: string]: Conditions } type Conditions = TestFunction | TestFunctionObject 例如

我需要使用一个或多个测试函数测试多个
HTMLInputElement
s的每个值,并自动为每个值生成一个复选框嵌套列表,条件表示为
conditions
,如下所示:

type TestFunction = (value: string) => boolean
type TestFunctionObject = { [description: string]: Conditions }
type Conditions = TestFunction | TestFunctionObject
例如,如果我有:

const conds1: Conditions = {
  "Consists of alphanumerics": /^[a-zA-Z0-9]$/.test
}
我得到一个标记为“由字母数字组成”的复选框。如果:

我不想要一个复选框,只是用它来验证

自动生成没有任何问题。然后,我编写了一个类型,它表示每个
TestFunction
的有效性:

type Validity<C extends Conditions> = C extends TestFunction
  ? boolean
  : { [K in keyof C]: Validity<C[K]> }
type Validity=C扩展了TestFunction
? 布尔值
:{[K in keyof C]:有效性}
现在我在
C[K]
;上从TS得到一个错误。它说,
Type“Conditions[K]”不能分配给类型“TestFunctionObject”
。类型条件似乎没有将
条件
缩小到只
TestFunctionObject

我怎样才能让它工作


的添加:

我认为编译器不会像通过控制流分析处理值那样,在条件类型的else子句中(在
之后)进行大量缩小。因此,很明显,在条件类型
C扩展TestFunction
中,else子句中的
C
应该扩展
TestFunctionObject
,但编译器没有实现它

但是编译器确实在then子句中进行了收缩(介于
之间),因此最简单的修复方法是添加另一个条件类型:

type Validity<C extends Conditions> = C extends TestFunction ? boolean
  : C extends TestFunctionObject ? { [K in keyof C]: Validity<C[K]> } : never

两者都应该有效。希望有帮助;祝你好运

如果我没有弄错的话,
true
分支(而不是false分支)中存在的狭窄是Anders在其著作中所暗示的,“……在
X
中对
T
的引用有一个额外的类型参数约束
U
”这也是您对该句子的解释吗?我在其他任何地方都没有看到这种行为的记录。是的,我同意。我在中看到了同一行,但它被隐藏在分布式条件类型部分。哇,我从后面看到了一个备忘!这个问题仅仅在于通过IntelliSense显示类型的方式,而不是实际的类型。有关显示错误,请参阅。请注意,在您的示例中,
validity3[“包括至少”][“1个基本拉丁大写字母”]
的类型为
boolean
,但
validity3[“包括至少”]。rando
是编译器错误(启用了
--noImplicitAny
type Validity<C extends Conditions> = C extends TestFunction ? boolean
  : C extends TestFunctionObject ? { [K in keyof C]: Validity<C[K]> } : never
type Validity<C extends Conditions> = C extends TestFunctionObject ?
  { [K in keyof C]: Validity<C[K]> } : boolean