typescript - 带有严格空检查的 RegExpMatchArray 的打字稿类型定义
问题描述
问题
我在 Typescript 严格模式(严格的空检查)中的可迭代对象(如果我的理解是正确的)遇到了一些问题。我想使用'String.prototype.match()'的返回对象。
const matchLetter: RegExpMatchArray | null = points[0].match(/[a-zA-Z]/);
const direction: Tdirection = matchLetter[0];
// Two errors:
// 1. Object is possibly 'null'. ts(2531)
// 2. Type 'string' is not assignable to type 'Tdirection'. ts(2322)
我正在尝试做的事情:
// don't change RegExpMatchArray, it's from typescript lib.es5.d.ts
interface RegExpMatchArray extends Array<string> { index?: number; input?: string; }
// custom types
type Tlocation = { x: number; y: number };
type Tdirection = "R" | "U" | "L" | "D";
// demo data
const pathToPlot = [["R0", "R1", "R2"],["U0", "U1"],["L0"],["D0"]];
// demo operations
const operations = {
R: (index: number, lastLocation: Tlocation) => { return { x: lastLocation.x + index, y: lastLocation.y }},
U: (index: number, lastLocation: Tlocation) => { return { x: lastLocation.x + index, y: lastLocation.y }},
L: (index: number, lastLocation: Tlocation) => { return { x: lastLocation.x - index, y: lastLocation.y }},
D: (index: number, lastLocation: Tlocation) => { return { x: lastLocation.x, y: lastLocation.y - index }}
};
pathToPlot.forEach(points => {
// In JS I did it like this:
// const direction = points[0].match(/[a-zA-Z]/)[0];
// Typescript equivalent?
const matchLetter: RegExpMatchArray | null = points[0].match(/[a-zA-Z]/);
// This is giving errors:
const direction: Tdirection = matchLetter[0];
// two errors:
// 1. Object is possibly 'null'. ts(2531)
// 2. Type 'string' is not assignable to type 'Tdirection'. ts(2322)
console.log(operations[direction](1, { x: 0, y: 0 }));
});
到目前为止我做了什么:
我已经阅读了几篇关于这个问题的文章。
一个建议是为 RegExpArray 定义一个新类型(在此处描述)。但是重新定义现有类型似乎很奇怪。我宁愿使用现有的并围绕它执行我自己的逻辑以使其通过。
我还阅读了文章“如何避免 Javascript 中的 null 检查污染:使用 Optionals”(文章)。它指出您可以使用一个库,该库提供了一种检查值是否为空的方法。如果是这样,它会使用错误消息对其进行处理,然后返回其他内容。
不使用图书馆就没有办法吗?
解决方案
您必须先检查 null :
const matchLetter: RegExpMatchArray | null = points[0].match(/[a-zA-Z]/);
if (matchLetter) {
const direction: Tdirection = matchLetter[0];
}
如果 Typescript 没有自动识别出该matchLetter
值已经被检查过,那么让它显式:
const matchLetter: RegExpMatchArray | null = points[0].match(/[a-zA-Z]/);
if (matchLetter) {
const direction: Tdirection = matchLetter![0] as Tdirection;
}
尾随!
是所谓的非空断言操作符,它明确表示可空变量此时将包含一个值。如果我们在访问matchLetter
. 但我见过 Typescript linter 仍然抱怨的情况。
错误direction
很明显,因为您试图将通用字符串分配给字符串枚举。我已经更改了上面的代码以使用as
强制转换来使 linter 静音。
更改direction
分配后,最后还需要更改operations
表达式:
var direction: Tdirection | undefined;
if (matchLetter) {
direction = matchLetter[0] as Tdirection;
}
if (direction) {
console.log(operations[direction](1, { x: 0, y: 0 }));
}
推荐阅读
- html - Github 页面 404 找不到文件
- sql - 通过外键约束强制关系?
- php - 在 Laravel 中重命名 API 名称
- scikit-learn - AttributeError:在管道上调用 fit_transform 时,“numpy.ndarray”对象没有属性“fit”
- javascript - 将函数加载到 HTML//生成随机词
- javascript - 使用 .forEach() 动态生成数组
- javascript - 使用 Selenium/BeautifulSoup 抓取动态网站
- jquery - 带有颜色框的 HTML 颜色选择器
- latex - Markdown 方程对齐
- asp.net-core - 如何使用 Asp.Net Core Identity 为多个位置/站点扩展角色