Bal*_*des 6 abstract-syntax-tree typescript typescript-compiler-api
考虑以下接口:
interface X {
x: string
}
Run Code Online (Sandbox Code Playgroud)
我正在尝试使用 typescript 编译器 API 来获取 propertyx
的类型。这是我到目前为止所拥有的:
import {
PropertySignature,
createSourceFile,
ScriptTarget,
ScriptKind,
SyntaxKind,
InterfaceDeclaration,
Identifier,
} from 'typescript'
describe('Compiler test', () => {
it('should be able to find type information about X.x', () => {
const sourceText = 'interface X { x: string }'
const ast = createSourceFile('source.ts', sourceText, ScriptTarget.ES5, false, ScriptKind.TS)
const interfaceX = ast
.getChildAt(0)
.getChildren()
.find((child) => child.kind === SyntaxKind.InterfaceDeclaration) as InterfaceDeclaration
const propX = interfaceX.members.find((member) => (member.name as Identifier).escapedText === 'x')
console.log(JSON.stringify(propX, null, 2))
})
})
Run Code Online (Sandbox Code Playgroud)
现在propX
节点的内容如下:
{
"pos": 13,
"end": 23,
"flags": 0,
"kind": 151,
"name": {
"pos": 13,
"end": 15,
"flags": 0,
"escapedText": "x"
},
"type": {
"pos": 16,
"end": 23,
"flags": 0,
"kind": 137
}
}
Run Code Online (Sandbox Code Playgroud)
从中可以清楚地提取节点的名称,但是类型节点似乎没有任何有用的信息。
我如何获得房产的类型信息?我只需要"string"
.
所以这样做的方法是构建一个Program
(需要一个CompilerHost
来做)并使用TypeChecker
@MattMcCutchen建议的:
在CompilerHost
(你不需要一个类的实现,但我发现它更方便):
export const SAMPLE_FILE_NAME = 'sample.ts'
export class TestCompilerHost implements CompilerHost {
constructor(private readonly code: string) {}
fileExists = () => true
getCanonicalFileName = () => SAMPLE_FILE_NAME
getCurrentDirectory = () => ''
getDefaultLibFileName = () => 'lib.d.ts'
getDirectories = () => []
getNewLine = () => '\n'
readFile = () => null
useCaseSensitiveFileNames = () => true
writeFile = () => {}
getSourceFile(filename: string): SourceFile {
return createSourceFile(filename, this.code, ScriptTarget.ES5, true)
}
}
Run Code Online (Sandbox Code Playgroud)
建立一个Program
:
const config: CompilerOptions = {
noResolve: true,
target: ScriptTarget.ES5,
}
const sourceText = `interface X { x: string }`
const program = createProgram([SAMPLE_FILE_NAME], config, new TestCompilerHost(sourceText))
Run Code Online (Sandbox Code Playgroud)
找到问题中的接口和属性(唯一的区别是访问 SourceFile 的方式):
const ast = program.getSourceFile(SAMPLE_FILE_NAME)
const interfaceX = ast
.getChildAt(0)
.getChildren()
.find((child) => child.kind === SyntaxKind.InterfaceDeclaration) as InterfaceDeclaration
const propX = interfaceX.members.find((member) => (member.name as Identifier).escapedText === 'x')
Run Code Online (Sandbox Code Playgroud)
最后得到类型:
const typeChecker = program.getTypeChecker()
const type = typeChecker.getTypeAtLocation(propX.type)
const stringType = typeChecker.typeToString(type)
Run Code Online (Sandbox Code Playgroud)
propX
与我的问题中相同的变量在哪里。
归档时间: |
|
查看次数: |
1542 次 |
最近记录: |