我似乎无法使用编译器API获取变量的类型。 下面我的示例的一些上下文。 因为我在内存中运行所有内容,所以我必须创建自己的编译器主机。这是必要的,因为类型检查器是从“程序”创建的。并且这要求默认文件写入磁盘。
我尝试输入"输入"和" el"。我希望这打印出来#34;数字[]"和"数字"。这就像我将鼠标悬停在VSCode上一样。
然而,我得到的输出是" {}"或"任何"。
我确定我做错了什么或忘记了什么,但我不知道它是什么。
祝你好运, 艾克
const code: string = `let input: number[] = [1, 2, 3];
for (let el of input) {
let x = el * 3;
if (el > 1) {
output.push(el);
}
}`;
const host: ts.CompilerHost = {
getSourceFile(fileName: string, languageVersion: ts.ScriptTarget, onError?: (message: string) => void): ts.SourceFile {
console.log("getSourceFile", fileName);
if (fileName === "test.ts") {
return ts.createSourceFile(fileName, code, languageVersion);
}
if (onError) {
onError("not found");
}
// tsc's declarations don't support strict null checks
return null as any as ts.SourceFile;
},
getDefaultLibFileName: () => "", // "lib.d.ts",
writeFile: (_fileName, _content) => { },
getCurrentDirectory: () => ts.sys.getCurrentDirectory(),
getCanonicalFileName: fileName => ts.sys.useCaseSensitiveFileNames ? fileName : fileName.toLowerCase(),
getNewLine: () => ts.sys.newLine,
useCaseSensitiveFileNames: () => ts.sys.useCaseSensitiveFileNames,
fileExists: (fileName: string) => fileName === "test.ts",
readFile(fileName: string): string {
if (fileName === "test.ts") {
return code;
}
return null as any as string;
},
resolveModuleNames(_moduleNames: string[], _containingFile: string): ts.ResolvedModule[] {
throw new Error("unsupported");
},
getDirectories(_path: string): string[] {
throw new Error("unsupported");
}
};
const program: ts.Program = ts.createProgram(["test.ts"], {allowJs: true}, host);
const checker: ts.TypeChecker = program.getTypeChecker();
const forofke: ts.ForOfStatement = program.getSourceFiles()[0].statements[1];
const stat = forofke.expression;
const type1: ts.Type = checker.getTypeAtLocation(stat);
console.log(checker.typeToString(type1));
const sym: ts.Symbol = checker.getSymbolAtLocation(stat);
const type2: ts.Type = checker.getDeclaredTypeOfSymbol(sym);
console.log(checker.typeToString(type2));
const type3: ts.Type = checker.getTypeOfSymbolAtLocation(sym, stat);
console.log(checker.typeToString(type3));
const type4: ts.Type = checker.getTypeOfSymbolAtLocation(sym, sym.valueDeclaration);
console.log(checker.typeToString(type4));
const stat2 = (<ts.VariableDeclarationList>forofke.initializer).declarations[0].name;
const type12: ts.Type = checker.getTypeAtLocation(stat2);
console.log(checker.typeToString(type12));
const sym2: ts.Symbol = checker.getSymbolAtLocation(stat2);
const type22: ts.Type = checker.getDeclaredTypeOfSymbol(sym2);
console.log(checker.typeToString(type22));
const type32: ts.Type = checker.getTypeOfSymbolAtLocation(sym2, stat2);
console.log(checker.typeToString(type32));
const type42: ts.Type = checker.getTypeOfSymbolAtLocation(sym2, sym2.valueDeclaration);
console.log(checker.typeToString(type42));
答案 0 :(得分:0)
我比较了一个&#39;程序&#39;从我的样本中从磁盘加载到内存中的那个。我注意到,从磁盘中有两个源文件,在program.getSourceFiles()&#39;中。第二个文件是lib.d.ts。
我稍微更改了我的样本,现在输出就像我预期的那样。
getSourceFile(fileName: string, languageVersion: ts.ScriptTarget, onError?: (message: string) => void): ts.SourceFile {
console.log("getSourceFile", fileName);
if (fileName === "test.ts") {
return ts.createSourceFile(fileName, code, languageVersion);
}
if (fileName === "lib.d.ts") {
return ts.createSourceFile(fileName, /*READ the file from disk*/, languageVersion);
}
if (onError) {
onError("not found");
}
// tsc's declarations don't support strict null checks
return null as any as ts.SourceFile;
},
getDefaultLibFileName: () => "lib.d.ts",