我想获得节点。参数属性Typescript类型的名称,并检查它是否为Foo。
假设Foo类型是这样定义的:
type Foo = {};
这是目前为止我的eslint规则定义。
import { createRule, } from "../utils";
export default createRule({
name: 'disallow-foo-type-spread',
meta: {
type: 'suggestion',
docs: {
description: 'Bans spread operator from being used on foo.',
recommended: 'error',
},
messages: {
noSpread: "Don't spread foo"
},
schema:[{}]
},
defaultOptions: [{}],
create(context) {
return {
SpreadElement(node) {
console.log(node.argument);
if (node.argument.typeName === "Foo") {
context.report({
node,
messageId: "noSpread",
});
}
},
};
}
});
但是typeName没有定义。使用astexplorer.net https://astexplorer.net/#/gist/c6a63070e9678f906f1c61d3087d8027/f659343aa025059f2220d27217cb6b03d733e92b
如果我们使用asterexplorer.net来检查以下代码:https://astexplorer.net/#/gist/c6a63070e9678f906f1c61d3087d8027/f659343aa025059f2220d27217cb6b03d733e92b
type Foo = {};
const foo: Foo = {}
const moo = {...foo}
我们可以看到触发SpreadElement RuleListener的...foo
节点根本没有Foo
类型。
这似乎行得通:
import { ESLintUtils } from "@typescript-eslint/utils";
...
create(context) {
const parserServices = ESLintUtils.getParserServices(context);
const checker = parserServices?.program?.getTypeChecker();
return {
SpreadElement(node) {
const expression = parserServices.esTreeNodeToTSNodeMap.get(
node.argument
);
const symbol = checker?.getTypeAtLocation(expression)?.getSymbol();
const type = symbol?.escapedName?.toString() || "";
if (type === "Foo") {
context.report({
node,
messageId: "noSpread",
});
}
},
};
}