Babel.js obj.prop和obj ['prop']在 typescript 中的区别?

zlwx9yxi  于 2022-12-08  发布在  Babel
关注(0)|答案(2)|浏览(167)

在使用@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);

我对这两种类型写作的区别感到困惑?
谢谢你的回答

ijxebb2r

ijxebb2r1#

您可以在JavaScript/typescript中存取对象的属性:
1..属性存取子:object.property
1.方括号属性访问:对象['属性']

何时用途:

如果事先知道属性名称,请选择dot属性存取子。
例如

const hero = {
  name: 'XYZ'
};

这里属性已经提前知道,所以我们可以使用hero.name
如果属性名称是动态的(即在运行时确定),请选择方括号属性访问器。
例如:

const property = 'name';
const hero = {
  name: 'XYZ'
};

// Square brackets property accessor:
hero['name'];   //output => 'XYZ'
hero[property]; //output => 'XYZ'

这里的属性是在运行时确定的,因此我们使用方括号。
因此,如果您在运行时确定的属性上使用属性点访问器,typescript将给予错误
类型hero上不存在属性'name'
访问属性的方法没有好坏之分。请根据您的具体情况进行选择。
详细解释在这里通过Dmitri Pavlutin

pqwbnv8z

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成员的对象表达式的方法:

import { parse } from "@babel/parser";
import { isExpressionStatement, isObjectExpression } from "@babel/types";

const ast = parse('({key: "something"})', {
    sourceType: "module",
    plugins: ["typescript"],
});

let firstStatement = ast.program.body[0];
if (!isExpressionStatement(firstStatement) || !isObjectExpression(firstStatement.expression)) {
    throw Error("Expected statement not found");
}

console.log(firstStatement.expression.properties);

Playground链接
注意:我把{key: "something"}改成了({key: "something"})。我假设你正在解析一个对象文字。你的版本实际上是一个块语句,里面有一个标签语句。块语句vs对象文字

相关问题