faw*_*ell 4 typescript typescript-typings
我想在打字稿中创建一个类型,它可以将字符串转换为大写:
type _Upper<T> = ...
_Upper<'abc'> // 'ABC'
Run Code Online (Sandbox Code Playgroud)
谁能告诉我这个吗?
正确的方法是仅使用现有的Uppercase<T>实用程序类型。这是microsoft/TypeScript#40580intrinsic中引入的类型,这意味着它是在编译器本身中实现的;你可以查看大约第 15,085 行:checker.ts
case IntrinsicTypeKind.Uppercase: return str.toUpperCase()\nRun Code Online (Sandbox Code Playgroud)\n_Upper<T>这意味着您可以像这样定义自定义类型:
type _Upper<T extends string> = Uppercase<T>;\nRun Code Online (Sandbox Code Playgroud)\n是的,这是一个微不足道的定义。但它的优点是定义简单并且根据Unicode 标准大小写映射算法工作:
\ntype ABC = _Upper<\'abc\'>\n// type ABC = "ABC"\n\ntype Sentence = _Upper<"The quick brown fox jumps over the lazy dog.">;\n// type Sentence = "THE QUICK BROWN FOX JUMPS OVER THE LAZY DOG."\n\ntype \xd0\xa5\xd0\xbe\xd1\x80\xd0\xbe\xd1\x88\xd0\xbe = Uppercase<"\xd1\x8f \xd0\xbd\xd0\xb5 \xd0\xb7\xd0\xbd\xd0\xb0\xd1\x8e">;\n// type \xd0\xa5\xd0\xbe\xd1\x80\xd0\xbe\xd1\x88\xd0\xbe = "\xd0\xaf \xd0\x9d\xd0\x95 \xd0\x97\xd0\x9d\xd0\x90\xd0\xae"\nRun Code Online (Sandbox Code Playgroud)\n如果您不想使用Uppercase<T>,您可以使用递归模板文字类型来自己实现一些东西。但请注意,要准确地做到这一点,您需要保留所有 Unicode 字符的映射,这些字符在转换为大写时需要更改。至少这将是一个相当大的映射(我认为超过 2,000 个字符)。
如果你只关心拉丁字母的 26 个字符,那么你可以这样写:
\ninterface Uppers {\n a: "A", b: "B", c: "C", d: "D", e: "E", f: "F", g: "G", \n h: "H", i: "I", j: "J", k: "K", l: "L", m: "M",\n n: "N", o: "O", p: "P", q: "Q", r: "R", s: "S", t: "T", \n u: "U", v: "V", w: "W", x: "X", y: "Y", z: "Z"\n}\n\ntype _Upper<T extends string, A extends string = ""> =\n T extends `${infer F}${infer R}` ?\n _Upper<R, `${A}${F extends keyof Uppers ? Uppers[F] : F}`> : A;\nRun Code Online (Sandbox Code Playgroud)\nUppers从小写(键)到大写(值)的映射类型也是如此。该_Upper<T>类型逐个字符T地解析字符串。如果字符F是小写 ( F extends keyof Uppers),则将其转换为大写 ( Uppers[F]),否则将其保留(F)。这是一个尾递归定义(使用A类型参数作为累加器),因此在 TypeScript 4.5 及更高版本中,这适用于相当长的字符串文字。
让我们测试一下:
\ntype ABC = _Upper<\'abc\'>\n// type ABC = "ABC"\n\ntype Sentence = _Upper<"The quick brown fox jumps over the lazy dog.">;\n// type Sentence = "THE QUICK BROWN FOX JUMPS OVER THE LAZY DOG."\n\ntype \xd0\x9f\xd0\xbb\xd0\xbe\xd1\x85\xd0\xbe = _Upper<"\xd1\x8f \xd0\xbd\xd0\xb5 \xd0\xb7\xd0\xbd\xd0\xb0\xd1\x8e">;\n// type \xd0\x9f\xd0\xbb\xd0\xbe\xd1\x85\xd0\xbe = "\xd1\x8f \xd0\xbd\xd0\xb5 \xd0\xb7\xd0\xbd\xd0\xb0\xd1\x8e" // oops\nRun Code Online (Sandbox Code Playgroud)\n嗯,前两个都不错。
\n但最后一个不起作用;小写西里尔字母字符串不受影响。如有必要,可以通过Uppers使用西里尔字母增强类型来解决此问题。这里的基本算法,解析字符串并查找映射中的每个字符,可能是我们能做的最好的算法。嗯,最好的办法是使用内置的Uppercase<T>. 但如果Uppercase<T>不存在,那么像这样的递归条件模板文字类型将是合理的。
| 归档时间: |
|
| 查看次数: |
3269 次 |
| 最近记录: |