正如@RyanCavanaugh 所说,TypeScript 没有不区分大小写的字符串文字。 [编辑:提醒我,TypeScript 有一个现有的suggestion 来支持正则表达式验证的字符串文字,这可能会允许这样做,但它目前不是语言的一部分。]
我能想到的唯一解决方法是枚举这些文字的最可能变体(例如,全小写,init cap)并创建一个可以在需要时在它们之间进行转换的函数:
namespace XhrTypes {
function m<T, K extends string, V extends string>(
t: T, ks: K[], v: V
): T & Record<K | V, V> {
(t as any)[v] = v;
ks.forEach(k => (t as any)[k] = v);
return t as any;
}
function id<T>(t: T): { [K in keyof T]: T[K] } {
return t;
}
const mapping = id(m(m(m(m(m(m(m({},
["get", "Get"], "GET"), ["post", "Post"], "POST"),
["put", "Put"], "PUT"), ["delete", "Delete"], "DELETE"),
["options", "Options"], "OPTIONS"), ["connect", "Connect"], "CONNECT"),
["head", "Head"], "HEAD"));
export type Insensitive = keyof typeof mapping
type ForwardMapping<I extends Insensitive> = typeof mapping[I];
export type Sensitive = ForwardMapping<Insensitive>;
type ReverseMapping<S extends Sensitive> =
{[K in Insensitive]: ForwardMapping<K> extends S ? K : never}[Insensitive];
export function toSensitive<K extends Insensitive>(
k: K ): ForwardMapping<K> {
return mapping[k];
}
export function matches<K extends Insensitive, L extends Insensitive>(
k: K, l: L ): k is K & ReverseMapping<ForwardMapping<L>> {
return toSensitive(k) === toSensitive(l);
}
}
最终导出的是以下类型:
type XhrTypes.Sensitive = "GET" | "POST" | "PUT" | "DELETE" |
"OPTIONS" | "CONNECT" | "HEAD"
type XhrTypes.Insensitive = "get" | "Get" | "GET" |
"post" | "Post" | "POST" | "put" | "Put" | "PUT" |
"delete" | "Delete" | "DELETE" | "options" | "Options" |
"OPTIONS" | "connect" | "Connect" | "CONNECT" | "head" |
"Head" | "HEAD"
和功能
function XhrTypes.toSensitive(k: XhrTypes.Insensitive): XhrTypes.Sensitive;
function XhrTypes.matches(k: XhrTypes.Insensitive, l: XhrTypes.Insensitive): boolean;
我不确定你 (@Knu) 需要这个做什么或你打算如何使用它,但我想你想在敏感/不敏感方法之间转换,或者检查两个不区分大小写的方法方法是匹配的。显然,您可以在运行时通过转换为大写或进行不区分大小写的比较来执行这些操作,但在编译时上述类型可能很有用。
这是一个使用它的例子:
interface HttpStuff {
url: string,
method: XhrTypes.Insensitive,
body?: any
}
const httpStuff: HttpStuff = {
url: "https://google.com",
method: "get"
}
interface StrictHttpStuff {
url: string,
method: XhrTypes.Sensitive,
body?: any
}
declare function needStrictHttpStuff(httpStuff: StrictHttpStuff): Promise<{}>;
needStrictHttpStuff(httpStuff); // error, bad method
needStrictHttpStuff({
url: httpStuff.url,
method: XhrTypes.toSensitive(httpStuff.method)
}); // okay
在上面,有一个函数需要大写值,但如果你首先使用XhrTypes.toSensitive(),你可以安全地传递一个不区分大小写的值,编译器会验证"get"是"GET"的可接受变体这个案例。
好的,希望对您有所帮助。祝你好运。