mar*_*eto 8 types case-insensitive typescript typescript-typings
我在TypeScript中有这个类型定义:
export type xhrTypes = "GET" | "POST" | "PUT" | "DELETE" | "OPTIONS" | "CONNECT" | "HEAD";
Run Code Online (Sandbox Code Playgroud)
遗憾的是,这是区分大小写的...有没有办法定义它不区分大小写?
谢谢
jca*_*alz 14
欢迎回来!既然 TypeScript 4.1 已经引入了模板字面量类型和Uppercase/Lowercase内在字符串映射类型,我们现在可以在不需要正则表达式类型的情况下回答这个问题。
主要有两种方法。“蛮力”方法大量使用递归条件类型和联合,将您xhrTypes变成所有可能的写字符串方式的具体联合,其中大小写无关紧要:
type xhrTypes = "GET" | "POST" | "PUT" | "DELETE" | "OPTIONS" | "CONNECT" | "HEAD";
type AnyCase<T extends string> =
string extends T ? string :
T extends `${infer F1}${infer F2}${infer R}` ? (
`${Uppercase<F1> | Lowercase<F1>}${Uppercase<F2> | Lowercase<F2>}${AnyCase<R>}`
) :
T extends `${infer F}${infer R}` ? `${Uppercase<F> | Lowercase<F>}${AnyCase<R>}` :
""
type AnyCaseXhrTypes = AnyCase<xhrTypes>;
Run Code Online (Sandbox Code Playgroud)
如果您检查AnyCaseXhrTypes,您会看到它是一个拥有 368 名成员的工会:
/* type AnyCaseXhrTypes = "GET" | "POST" | "PUT" | "DELETE" | "OPTIONS" |
"CONNECT" | "HEAD" | "GEt" | "GeT" | "Get" | "gET" | "gEt" | "geT" | "get" |
"POSt" | "POsT" | "POst" | "PoST" | "PoSt" | "PosT" | "Post" |
... 346 more ... | "head" */
Run Code Online (Sandbox Code Playgroud)
然后你可以使用这种类型来代替xhrType你想要不区分大小写的任何地方:
function acceptAnyCaseXhrType(xhrType: AnyCaseXhrTypes) { }
acceptAnyCaseXhrType("get"); // okay
acceptAnyCaseXhrType("DeLeTe"); // okay
acceptAnyCaseXhrType("poot"); // error! "poot" not assignable to big union
Run Code Online (Sandbox Code Playgroud)
蛮力方法的问题在于它不能很好地扩展更多或更长的字符串。TypeScript 中的联合类型限制为 100,000 个成员,并且在编译器抱怨之前,递归条件类型最多只能达到 20 级深度。因此,任何中等长度的单词或中等长度的单词列表都会使上述方法不可行。
type xhrTypes = "GET" | "POST" | "PUT" | "DELETE" | "OPTIONS" | "CONNECT" | "HEAD"
| "LONG STRINGS MAKE THE COMPILER UNHAPPY";
type AnyCaseXhrTypes = AnyCase<xhrTypes>; // error!
// Type instantiation is excessively deep and possibly infinite.
// Union type is too complex to represent
Run Code Online (Sandbox Code Playgroud)
解决这个问题的一种方法是不再使用特定的具体联合,而是切换到泛型类型表示。如果T是传递给 的字符串值的类型acceptAnyCaseXhrType(),那么我们要做的就是确保它Uppercase<T>可以分配给xhrType。这与其说是一种类型,不如说是一种约束(尽管我们不能直接使用泛型约束来表达这一点):
function acceptAnyCaseXhrTypeGeneric<T extends string>(
xhrType: Uppercase<T> extends xhrTypes ? T : xhrTypes
) { }
acceptAnyCaseXhrTypeGeneric("get"); // okay
acceptAnyCaseXhrTypeGeneric("DeLeTe"); // okay
acceptAnyCaseXhrTypeGeneric("poot"); // error! "poot" not assignable to xhrTypes
Run Code Online (Sandbox Code Playgroud)
此解决方案要求您将泛型类型参数拉到您可能不需要它们的地方,但它确实可以很好地扩展。
所以,你去!我们所要做的就是等待......(检查笔记)...... 3 年,TypeScript 交付了!
就这样,这篇文章有一个答案:不,这是不可能的.
更新5/15/2018:仍然不可能.最接近的是,正则表达式验证的字符串类型,在语言设计会议上提出的最近时间并没有被广泛接受.
| 归档时间: |
|
| 查看次数: |
2959 次 |
| 最近记录: |