在使用@babel/parser解析一些字符串并获得ast后,我在使用obj.prop类型记录ast时遇到了一个错误,但在使用obj ['prop']类型时它可以工作
import { parse } from "@babel/parser";
import traverse from "@babel/traverse";
const ast = parse('{key: "something"}', {
sourceType: "module",
plugins: ["typescript"],
});
// Property 'declaration' does not exist on type 'Statement'. Property 'declaration' does not exist on type 'BlockStatement'.ts(2339)
console.log(ast.program.body[0].declaration.properties);
// it's good
console.log(ast.program.body[0]["declaration"].properties);
我对这两种类型写作的区别感到困惑?
谢谢你的回答
2条答案
按热度按时间ijxebb2r1#
您可以在JavaScript/typescript中存取对象的属性:
1..属性存取子:object.property
1.方括号属性访问:对象['属性']
何时用途:
如果事先知道属性名称,请选择dot属性存取子。
例如
这里属性已经提前知道,所以我们可以使用hero.name
如果属性名称是动态的(即在运行时确定),请选择方括号属性访问器。
例如:
这里的属性是在运行时确定的,因此我们使用方括号。
因此,如果您在运行时确定的属性上使用属性点访问器,typescript将给予错误
类型hero上不存在属性'name'
访问属性的方法没有好坏之分。请根据您的具体情况进行选择。
详细解释在这里通过Dmitri Pavlutin。
pqwbnv8z2#
你可以用点标记法或括号标记法访问typescript中的属性。不过,这两种标记法在错误方面是有区别的,具体取决于编译器的选项。
如果将
noImplictAny
设置为false
(默认值),即使编译时无法检查该属性是否有效,也不会出现括号表示法错误,只会得到一个隐式的any
。因此,ast.program.body[0]["declaration"]
将为any
,并且typescript不会检查后面的.properties
。Playground Link如果您将
noImplictAny
设置为true,typescript将报告无法检查declaration
是否确实是ast.program.body[0]
的属性,并且您将得到两个错误(不可否认,错误略有不同)Playground Link在访问
ast.program.body[0]
的成员之前,您可能需要对它的类型进行一些缩小。下面是一种将ast.program.body[0]
缩小为表达式语句,然后再缩小为包含properties
成员的对象表达式的方法:Playground链接
注意:我把
{key: "something"}
改成了({key: "something"})
。我假设你正在解析一个对象文字。你的版本实际上是一个块语句,里面有一个标签语句。块语句vs对象文字