typescripttypescript-compiler-api

Is there a native typescript-compiler way to get the inferred type of a Map?


Given the Typescript declaration:

export const map = new Map([
    [1, 'one'],
    [2, 'two'],
]);

, I would like to get the inferred type, ie: Map<number, string>, using only the native compiler API (Version 5.0.4).

This is the AST in AST-viewer

It correctly identifies the type of the <NewExpression>, but digging in their code shows that they are using a non-native library, "ts-morph".

My logic has been so far:

const checker ... //<ts.TypeChecker>
const fileNode ... //<ts.SourceFile>
const fileSymbol = checker.getSymbolAtLocation(fileNode)! //returns <ts.Symbol>
const fileType = checker.getTypeOfSymbol(fileSymbol)! //returns <ts.Type>
const mapSymbol = fileType.getProperty('map')! //returns <ts.Symbol>
console.log(mapSymbol.getName()) //"map"


checker.getTypeOfSymbol(mapSymbol) //returns a <ts.Type>.intrinsicName: 'error'

I was expecting to get a valid <ts.Type> from the symbol.

I have tried extracting the type from all the ancestors, but have had no success. I have also tried <ts.NewExpression>.typeArguments, but this is undefined. The closest I have got is <ts.NewExpression>.arguments, but I want to avoid parsing them with a 3rd party or custom type extractor.

I suspect my inexperience with the compiler API is causing me to miss something obvious, but again, maybe not. A steer in the right direction would be much appreciated.


Solution

  • Check the result of ts.getPreEmitDiagnostics(program). Sounds like there's an error.

    The following works for me:

    const mapType = checker.getTypeOfSymbol(mapSymbol);
    console.log(mapType.getSymbol().getName()); // Map
    console.log(checker.getTypeArguments(mapType)); // [number, string]
    console.log(checker.typeToString(mapType)); // Map<number, string>
    

    This is the AST in AST-viewer

    It correctly identifies the type of the , but digging in their code shows that they are using a non-native library, "ts-morph".

    It uses the TypeScript compiler directly. It doesn't use ts-morph on the website at all.