我正在使用TypeScript和如下正则表达式解析文件名:
import { Filename } from '../models/filename';
const FILENAME_REGEX = /^(?<slug>.*?)(\.(?<language>[a-z]{2}))?(\.|\-(?<region>[A-Z]{2})\.)(?<extension>[a-z]*)$/i;
export const parseFilename = (filename: string): Filename => {
const result = FILENAME_REGEX.exec(filename);
if (result?.groups && result.groups['slug'] && result.groups['extension']) {
return {
slug: result.groups['slug'],
language: result.groups['language'],
region: result.groups['region'],
extension: result.groups['extension']
};
}
throw new Error("Filename doesn't match pattern");
};
文件名模型如下所示:
export interface Filename {
slug: string;
language?: string;
region?: string;
extension: string;
}
我的问题是,如果该region
组未为文件名定义page.en.md
,我将得到一个返回的对象,如...
{
slug: "page",
language: "en",
region: undefined,
extension: "md"
}
..有没有一种干净的方法,如果没有,那么就不会得到像这样的对象?:
{
slug: "page",
language: "en",
extension: "md"
}
有未定义键和未定义键的理由或用例是什么?
我不确定您认为“干净”的是什么。如果您想使用函数式编程,并且不介意进行一些类型声明,则可以这样进行:
return (['slug', 'language', 'region', 'extension'] as const).
filter(k => typeof result.groups?.[k] !== "undefined").reduce(
(f, k) => (f[k] = result.groups?.[k]! , f),
{} as Filename);
具有以下输出:
console.log(parseFilename("foo.html"))
// {slug: "foo", extension: "html"}
console.log(parseFilename("bar.en.html"))
// {slug: "bar", language: "en", extension: "html"}
console.log(parseFilename("baz.en-us.html"))
// {slug: "baz", language: "en", region: "us", extension: "html"}
贸易if
/else
对filter
可能不是一个巨大的胜利,但也许它满足您的需求?
但是我个人只是将undefined
属性值保留在那里,除非您知道事实会在某个地方引起麻烦。缺少的属性和现在-丁之间的区别undefined
属性是可观察到的(例如,prop in obj
是false
对前一种情况,并true
为后者的情况下),但在许多方面,他们是相同的(例如,obj[prop]
计算结果为undefined
)。TypeScript并不能真正一贯地区分它们,因此即使要表示语言的差异也很费力。因此,建议您in
在检查可选属性时注意不要使用等。
好吧,希望能有所帮助;祝好运!
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句