如何创建 Typescript 字符串类型,其中包含联合类型中的值并且以逗号分隔?
我认为这个不存在,但我还是想问......
type AcceptableVal = 'cool' | 'wow' | 'biz' | 'sweet' | 'yowza' | 'fantastic';
type Amaze = // how do you define this?;
const dabes: Amaze = 'cool,wow';
const fancy: Amaze = 'biz,wow,fantastic';
const hachiMachi: Amaze = 'yowza,biz,sweet';
Run Code Online (Sandbox Code Playgroud)
Ale*_*yne 16
您现在可以使用字符串模板文字类型来定义模式,例如:
type S = 'cool' | 'wow' | 'biz' | 'sweet' | 'yowza' | 'fantastic';
type Test = `${S},${S}`
Run Code Online (Sandbox Code Playgroud)
您仍然无法做的是使其可以像数组一样无限扩展。为了完成这项工作,打字稿将每个组合生成为一个联合。但对于像这样的小列表,它可以工作。
例如:
type S = 'cool' | 'wow' | 'biz' | 'sweet' | 'yowza' | 'fantastic';
type Amaze =
| `${S}`
| `${S},${S}`
| `${S},${S},${S}`
| `${S},${S},${S},${S}`
| `${S},${S},${S},${S},${S}`
| `${S},${S},${S},${S},${S},${S}`
Run Code Online (Sandbox Code Playgroud)
如果将鼠标悬停在 上Amaze,您将看到报告的类型:
type Amaze = S | "cool,cool" | "cool,wow" | "cool,biz" | "cool,sweet"
| "cool,yowza" | "cool,fantastic" | "wow,cool" | "wow,wow"
| "wow,biz" | "wow,sweet" | "wow,yowza" | "wow,fantastic"
| ... 55967 more ...| "fantastic,fantastic,fantastic,fantastic,fantastic,fantastic"
Run Code Online (Sandbox Code Playgroud)
请注意... 55967 more ...。Amaze 现在是一个具有超过五万五千个可能值的联合。此时这可能会影响 IDE 的性能。如果您添加需要 7 个字符串的版本,您将收到类型错误:
Expression produces a union type that is too complex to represent.(2590)
Run Code Online (Sandbox Code Playgroud)
最终,打字稿会因为性能原因而切断你的支持。但同样,对于小列表,这可能是可行的。
你不能。
Typescript 可以输入string可以包含任何内容的 s,也可以输入精确的字符串,例如"cool"或"wow"。但打字稿永远不会知道字符串是否包含某些字符。
实现此目的的唯一方法是将它们存储为数组:
type AmazeArray = AcceptableVal[];
const dabes: AmazeArray = ['cool', 'wow'];
Run Code Online (Sandbox Code Playgroud)
使用 ts4.1 的新模板字符串功能,您可以使用以下实用程序来执行此操作
type UnionToIntersection<U> = (U extends any ? (k: U) => void : never) extends (k: infer I) => void
? I
: never;
type UnionToOvlds<U> = UnionToIntersection<U extends any ? (f: U) => void : never>;
type PopUnion<U> = UnionToOvlds<U> extends (a: infer A) => void ? A : never;
type UnionConcat<U extends string, Sep extends string> = PopUnion<U> extends infer SELF
? SELF extends string
? Exclude<U, SELF> extends never
? SELF
:
| `${UnionConcat<Exclude<U, SELF>, Sep>}${Sep}${SELF}`
| UnionConcat<Exclude<U, SELF>, Sep>
| SELF
: never
: never;
Run Code Online (Sandbox Code Playgroud)
例子
type Keys = "a" | "b" | "c";
type Test = UnionConcat<Keys, ",">
// Test = "a" | "b" | "c" | "a,b" | "a,c" | "b,c" | "a,b,c"
type Test2 = UnionConcat<Keys, "-">
// Test2 = "a" | "b" | "c" | "a-b" | "a-c" | "b-c" | "a-b-c"
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
5138 次 |
| 最近记录: |