Kyl*_*Mit 5 recursion typescript variadic-tuple-types
我有一个查询元素数组,其中每个元素可以是一个术语或一个子查询,其中包含以“AND”或“OR”开头,后跟一组合法查询元素、术语或嵌套子查询等。
例如,这些都应该是合法的输入:
const query1 = "Hello"
const query2 = ["AND", "Hello", "World"]
const query3 = ["OR", ["AND", "Hello", "World"], ["AND", "Hola", "Mundo"]]
Run Code Online (Sandbox Code Playgroud)
TS 4.0中的Variadric Tuple应该允许您输入数组的第一个元素,并为其余元素输入另一种类型:
type IQuery = ["AND" | "OR", ...Array<string>]
const query = ["AND", "Hello", "World"] // valid
Run Code Online (Sandbox Code Playgroud)
TS 3.7中的递归类型应该允许您定义使用自身的类型:
type IQueryOps = string | Array<IQueryOps>
const query: IQueryOps = ["Hello", "World", ["Hola", "Mundo"]] // valid
Run Code Online (Sandbox Code Playgroud)
但当圆形类型展开时,我似乎无法将两者结合起来。在这种情况下,每个查询都以一个运算符开头,后面跟着一个字符串或另一个有效的查询,如下所示:
type IOperator = "AND" | "OR"
type IQuery = [IOperator, ...Array<string | IQuery>]
Run Code Online (Sandbox Code Playgroud)
在这种情况下,我收到错误:
类型别名“IQuery”循环引用自身。(2456)
无论如何,即使有解决方法,也可以输入此内容,还是我必须将其展开到我希望从类型角度支持的所需深度级别?
我认为这可能是microsoft/TypeScript#41164中报告的 TypeScript 设计限制的一个实例。正如那里提到的,
某些循环是允许的 [...] 但其他循环则不允许,例如
Run Code Online (Sandbox Code Playgroud)type Identity<T> = T; type T3 = Identity<T3>;通用实例化是deferred 的,因此在 TS 分析 [a] 声明时,它无法判断它是在 case 中
Record(将被允许)还是在Identitycase 中(将不允许)。只有在这个过程的后期,我们才能知道这实际上是好的,但如果不好,那么回去开始抱怨就“太晚了”。
如果这就是问题所在,那么虽然以下内容应该是“好的”,但编译器似乎无法尽早告知以允许它:
// type IQuery = string | ["AND" | "OR", ...Array<IQuery>] error
Run Code Online (Sandbox Code Playgroud)
(我稍微改变了你的定义以允许这条const query1 = "Hello"线)。
幸运的是,Array<T>有一个替代的内置语法T[],它似乎不会以这种方式延迟:
type IQuery = string | ["AND" | "OR", ...IQuery[]] // okay
Run Code Online (Sandbox Code Playgroud)
这有效:
const query1: IQuery = "Hello"
const query2: IQuery = ["AND", "Hello", "World"]
const query3: IQuery = ["OR", ["AND", "Hello", "World"], ["AND", "Hola", "Mundo"]]
const query4: IQuery = ["AND", ["OR", ["AND"]]];
const badQuery1: IQuery = 3; // error
// Type 'number' is not assignable to type 'IQuery'
const badQuery2: IQuery = ["AND", "Hello", 123]; // error
// Type 'number' is not assignable to type 'IQuery'
const badQuery3: IQuery =
["OR", query1, query2, "then", query3, query4, "if", []]; // error
// Type '[]' is not assignable to type 'IQuery'.
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
733 次 |
| 最近记录: |