Consider the following code:
// file1
export const VIEWPORT_HEIGHT = 1080;
// file2
import { VIEWPORT_HEIGHT } from '../../constants/app';
While processing file2, how can I get the value / type of VIEWPORT_HEIGHT? Given that it's a constant, its type will be 1080
, not number
. I'm trying to accomplish the same as VSCode which shows the constant value when you hover over the import:
While processing the import, I can analyse the following AST:
ImportDeclaration > ImportClause > NamedImports > ImportSpecifier > Identifier
I have access to the program
that webpack's ts-loader passes to getCustomTransformers and thus I have access to the type checker by doing:
let checker = program.getTypeChecker();
But I'm unable to reach the value / type. What am I missing?
I've figured this out.
I can pass any declaration to the type checker to obtain its value. Here's an example:
const ts = require('typescript');
function createConstInlinerTransformer(program) {
const factory = ts.factory;
const checker = program.getTypeChecker();
function transformerFactory(context) {
return {
transformSourceFile(sourceFile) {
const visitor = function (node) {
// The sourceFile node contains the following:
// sourceFile.symbol.exports
// sourceFile.locals
// We can use these to obtain the values of variables and imports.
// import
const firstImportClause = sourceFile.statements[0].importClause;
checker.getTypeAtLocation(firstImportClause.namedBindings.elements[0].symbol.declarations[0])
// local const
const localVar = sourceFile.locals.get('someVar');
checker.getTypeAtLocation(localVar.valueDeclaration);
// exported const
const exportedVar = sourceFile.symbol.exports.get('someExportedVar');
checker.getTypeAtLocation(exportedVar.valueDeclaration)
return ts.visitEachChild(node, visitor, context);
};
return ts.visitNode(sourceFile, visitor);
},
};
}
return transformerFactory;
}
module.exports = { createConstInlinerTransformer };