在 Typescript Template Literal 中使用 infer 关键字从句子中提取特定部分?
Extract specific parts from sentence by using infer keyword in Typescript Template Literal?
假设输入一个句子包含一个或两个空格并且具有${Verb}${one or two spaces}${Activity}
结构,我如何提取Typescript中的Verb
和Activity
?
type Split = ' ' | ' '
type ExtractVerb<S extends string> =
S extends `${infer Verb}${Split}${infer Activity}`
? [Verb, Activity]
: never;
type Verbs = ExtractVerb<"play chess" | "write code" | "read hacker news">
我得到了结果类型["play", "chess"] | ["write", " code" | "code"] | ["read" | "read hacker", "hacker news" | "news"]
。
预计:["play", "chess"] | ["write", "code"] | ["read", "hacker news"]
。
该行为的原因是 S
是一个联合,因此任何包含它的类型(例如 ${infer Verb}${Split}${infer Activity}
)都将被视为两个联合成员。所以打字稿会给你两种可能的结果。对于 "write code"
,您可以按 ' '
拆分并得到 ["write"
、" code"
] 或按 ' '
拆分并得到 ["write"
、" code"
].
您可以将 Split
字符串保存在一个元组中,并 运行 通过它们直到您使用递归条件类型获得匹配:
type Split = [' ', ' ']
type ExtractVerb<S extends string, Seprators extends string[] = Split> =
Seprators extends [infer FirstSeparator, ...infer RestSeparators] ?
S extends `${infer Verb}${FirstSeparator & string}${infer Activity}`
? [Verb, Activity]
: ExtractVerb<S, RestSeparators & string[]>
: never
type Verbs = ExtractVerb<"play chess" | "write code" | "read hacker news">
请注意,这是一个 tail recursive type,因此编译器应该可以很好地处理它。
假设输入一个句子包含一个或两个空格并且具有${Verb}${one or two spaces}${Activity}
结构,我如何提取Typescript中的Verb
和Activity
?
type Split = ' ' | ' '
type ExtractVerb<S extends string> =
S extends `${infer Verb}${Split}${infer Activity}`
? [Verb, Activity]
: never;
type Verbs = ExtractVerb<"play chess" | "write code" | "read hacker news">
我得到了结果类型["play", "chess"] | ["write", " code" | "code"] | ["read" | "read hacker", "hacker news" | "news"]
。
预计:["play", "chess"] | ["write", "code"] | ["read", "hacker news"]
。
该行为的原因是 S
是一个联合,因此任何包含它的类型(例如 ${infer Verb}${Split}${infer Activity}
)都将被视为两个联合成员。所以打字稿会给你两种可能的结果。对于 "write code"
,您可以按 ' '
拆分并得到 ["write"
、" code"
] 或按 ' '
拆分并得到 ["write"
、" code"
].
您可以将 Split
字符串保存在一个元组中,并 运行 通过它们直到您使用递归条件类型获得匹配:
type Split = [' ', ' ']
type ExtractVerb<S extends string, Seprators extends string[] = Split> =
Seprators extends [infer FirstSeparator, ...infer RestSeparators] ?
S extends `${infer Verb}${FirstSeparator & string}${infer Activity}`
? [Verb, Activity]
: ExtractVerb<S, RestSeparators & string[]>
: never
type Verbs = ExtractVerb<"play chess" | "write code" | "read hacker news">
请注意,这是一个 tail recursive type,因此编译器应该可以很好地处理它。