Typescript 컴파일러로 코드 식별
20155 단어 typescriptjavascript
예를 들어 AST로 모든 React 함수 구성 요소를 찾으려고 할 때 다음과 같이 단순화된 코드와 같이 Babel과 같은 도구의 도움이 필요할 수 있습니다.
import { transformSync, Visitor } from "@babel/core";
import { Identifier } from "@babel/types";
const funcs = [];
transformSync(content, {
parserOpts: {
plugins: ["jsx", "typescript", "classProperties", "optionalChaining"],
},
plugins: [
() => ({
visitor: {
ExportDefaultDeclaration({ node: { declaration } }) {
switch (declaration.type) {
case "FunctionDeclaration":
case "ArrowFuntionExpression":
funcs.push("default");
break;
}
},
ExportNamedDeclaration({ node }) {
const { declaration } = node;
if (declaration) {
switch (declaration.type) {
case "FunctionDeclaration":
if (declaration.id) {
funcs.push(declaration.id.name);
}
break;
case "VariableDeclaration":
declaration.declarations.forEach((d) => {
if (!d.id.name) return;
switch (d.init?.type) {
case "ArrowFunctionExpression":
funcs.push(d.id.name);
break;
}
});
break;
}
}
},
},
}),
],
});
console.log(funcs);
Here my little VSCode plugin Babel AST Explorer helped me saved a lot of time.
위
Visitors
는 다음 코드만 인식할 수 있습니다.export default function f() {}
export default () => {};
export function f() {}
export const f = () => {};
변수에 할당되면 식별하기가 더욱 어려워집니다. 예를 들어:
function f() {}
export { f };
export const f2 = f;
export default f;
이것은 저를 Typescript 컴파일러로 이끌었습니다.
그러나 document of Typescript compiler은 도움이 되지 않습니다. 작은 프로젝트에서 테스트한 Typescript 컴파일러 사용에 대한 몇 가지 참고 사항이 있습니다. 시간을 절약할 수 있기를 바랍니다.
기본 정의
Typescript 컴파일러는 몇 가지 기본 개체를 정의하며 저는 종종
Node
, Symbol
, Type
이 세 가지 개체를 사용하여 작업했습니다.내 이해로는
Symbol
는 Typescript가 컴파일러에서 통신하는 데 사용하는 주요 데이터 구조입니다. Node
는 토큰, 캐릭터 위치 등을 처리하는 AST 노드의 "상위 집합"입니다. Type
는 유형 안전성을 진단하기 위한 Typescript "유형"입니다. 따라서 우리는 항상 Symbol을 먼저 가져와야 하고, 필요하다면 Node나 Type을 요청해야 합니다.
예를 들어 다음과 같이 소스 코드에서 Symbol을 가져올 수 있습니다.
checker.getSymbolAtLocation(source);
여기서 "검사기"가 무엇인지 궁금할 수 있습니다. 다음 섹션에서 이에 대해 설명하겠습니다.
기호를 사용하면 다음과 같이 노드 유형에 따라 해당 노드를 찾을 수 있습니다.
symbol.declarations;
symbol.valueDeclaration;
유형으로 작업해야 하는 경우 Symbol 및 Node를 사용하여 얻을 수 있습니다.
checker.getTypeOfSymbolAtLocation(mySymbol, myNode);
또는 Node 유형에서 직접 가져옵니다.
checker.getTypeFromTypeNode(myNode);
유형 검사 유틸리티 시작
선언의 유형을 파악하려면 먼저 Typescript 유형 검사기를 시작하고 소스 코드를 Typescript 기호로 구문 분석해야 합니다.
import ts from "typescript";
import assert from "assert/strict";
const program = ts.createProgram({
rootNames: [file], // A set of root files
options: {}, // The compiler options
// There are 3 other options available but I am not sure what they are used for yet
});
const source = program.getSourceFile(file);
assert(source);
const checker = program.getTypeChecker();
const moduleSymbol = checker.getSymbolAtLocation(source);
assert(moduleSymbol);
ES 모듈의 내보내기 찾기
위에서 얻은 유형 검사기와 기호를 사용하면 ES 모듈 내보내기에서 분석을 계속하는 것이 Babel보다 훨씬 쉽습니다.
const exports = checker.getExportsOfModule(moduleSymbol);
exports.forEach((ex) => {
ex.declarations.forEach((d) => {
// ...
});
});
가장 가까운 유형 이름 인쇄
유형 검사기는 헬퍼와 가장 가까운 유형 이름을 제공할 수 있습니다.
const myType = checker.getTypeOfSymbolAtLocation(
mySymbol,
mySymbol.valueDeclaration!
);
checker.typeToString(myType);
글쎄요, 이 이름은 우리가 종종 유니온 또는 확장 유형을 사용하기 때문에 이 식별자가 우리가 찾고 있는 올바른 유형인지 식별하는 데 솔직히 별로 도움이 되지 않습니다. 불행히도 아직 더 나은 방법을 찾지 못했습니다. 내가 생각할 수 있는 한 가지 가능성은 코드 조각을 만들고 Typescript에 요청하여 전체 프로젝트에서 코드를 진단하는 것입니다.
플래그로 유형 구문 식별
Typescript 컴파일러는
SymbolFlags
, SyntaxKind
, ModifierFlags
등 여러 플래그를 정의했습니다. 가장 유용한 플래그는 SyntaxKind
입니다. SyntaxKind
는 다음과 같은 방식으로 Node
에서 유형 키워드를 식별하는 데 도움이 될 수 있습니다.if (myNode.kind === ts.SyntaxKind.NullKeyword) {
// This is a null type, do something
}
ModifierFlags
와 같은 일부 플래그에는 약간 더 많은 작업이 필요합니다.if (ts.getCombinedModifierFlags(myNode) & (ts.ModifierFlags.Export !== 0);) {
// I am exported, do something
}
ts 헬퍼로 노드 유형 식별
컴파일러는 어떤 종류의 코드를 다루고 있는지 식별하기 위한 일련의 도우미를 제공합니다. 예를 들어:
ts.isFunctionDeclaration(myNode);
ts.isArrowFunction(myNode);
ts.isVariableDeclaration(myNode);
ts.isIdentifier(myNode);
// ... and you can get more from auto-complete
이러한 도우미는
Node
와 함께 작동하며 구문 정의에 익숙한 경우 이름에서 매우 간단해 보입니다. 그러나 도우미 목록이 너무 길어서 Typescript가 ECMA, JSDoc 및 해당 타이핑 작업을 시도할 때 올바른 도우미를 찾을 수 없습니다.함수의 Type 개체 가져오기
경우에 따라 함수 또는 구문의 매개 변수 및 반환 유형을 알고 싶을 수 있습니다. 이를 달성하기 위해
Signature
개체에서 가져올 수 있는 Type
개체에서 시작합니다.checker
.getTypeOfSymbolAtLocation(mySymbol, mySymbol.valueDeclaration)
.getConstructSignatures()
.map((signature) => ({
parameters: signature.parameters.map((paramSymbol) =>
checker.getTypeOfSymbolAtLocation(
paramSymbol,
paramSymbol.valueDeclaration
)
),
returnType: signature.getReturnType(), // returns Type object
}));
Reference
이 문제에 관하여(Typescript 컴파일러로 코드 식별), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://dev.to/jennieji/identifying-code-with-typescript-compiler-bl9텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)