你如何解构命名的捕获组?

How do you destructure named capture groups?

In JavaScript, using named capture groups is pretty convenient:

const auth = 'Bearer AUTHORIZATION_TOKEN'
const { groups: { token } } = /Bearer (?<token>[^ $]*)/.exec(auth)
console.log(token) // "AUTHORIZATION_TOKEN"

当我在打字稿中尝试时,it doesn't compile 因为 groups 可能是 null。如果我在 exec(...) 之后放一个 !,它就会踢罐头:token 可能是未定义的。

在打字稿中,有什么方法可以像上面那样解构正则表达式?

更新 是完成此操作的更正确且类型安全的方法。


它很丑陋,但像这样的东西会起作用:

const auth = 'Bearer AUTHORIZATION_TOKEN'
type RegexTokenObj = { groups: { token: string } };
const { groups: { token } } = (/Bearer (?<token>[^ $]*)/.exec(auth) as unknown as RegexTokenObj)
console.log(token) // "AUTHORIZATION_TOKEN"

如果你只是尝试 const { groups: { token } } = (/Bearer (?<token>[^ $]*)/.exec(auth) as RegexTokenObj) 它会冲你大喊 "Conversion of type 'RegExpExecArray | null' to type 'RegexTokenObj' may be a mistake because neither type sufficiently overlaps with the other. If this was intentional, convert the expression to 'unknown' first." 因此我们可以在转换为 know/expect 类型之前转换为 unknown .也就是说,我们在这里重写了类型系统,所以我们应该确信我们这样做是正确的,所以要小心。

您还可以对 token 变量直接赋值:

const auth = 'Bearer AUTHORIZATION_TOKEN'
const token = /Bearer (?<token>\S+)/.exec(auth)?.groups?.token
console.log(token); // => "AUTHORIZATION_TOKEN"

既然知道组名,就可以参考group?.token匹配值

另外,注意 (?<token>\S+) 捕获一个或多个 non-whitespace 个字符。

It doesn't compile because groups could be null.

不,它不会编译,因为当正则表达式不匹配时 .exec() 可以 return null。尝试访问像 .groups 这样的 属性 会导致 TypeError: Cannot read properties of null.

在这种情况下,您需要一个后备值(使用 nullish coalescing 和默认初始化程序)来解构:

const { groups: {token} = {} } = /Bearer (?<token>[^ $]*)/.exec(auth) ?? {}

或更简单 optional chaining:

const { token } = /Bearer (?<token>[^ $]*)/.exec(auth)?.groups ?? {}