Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do you use the Typescript compiler's Typechecker to get the declared (alias) type, rather than the resolved type?

I realize this is somewhat obscure, but maybe someone else has run into this or knows the Typescript compiler well. I am processing Typescript files using Typescript's compiler API, based on examples like this: https://github.com/Microsoft/TypeScript/wiki/Using-the-Compiler-API

Imagine I have a declared function like this in Typescript:

export type DateString = string;
export function parseDate(date: DateString): Date{
    let parsedDate = Date.parse(date);
    let retVal = new Date();
    retVal.setTime(parsedDate);
    return retVal;
}

In the examples linked above, you can see methods like this defined to extract information about symbols:

function serializeSymbol(symbol: ts.Symbol): DocEntry {
    return {
        name: symbol.getName(),
        type: checker.typeToString(checker.getTypeOfSymbolAtLocation(symbol, symbol.valueDeclaration))
    };
}

When you run checker.typeToString(checker.getTypeOfSymbolAtLocation(symbol, symbol.valueDeclaration) on the date: DateString symbol, instead of returning DateString, it returns string. In other words, you don't get the declared type alias, but the fully resolved type. In my case, I'd like to know that the type of the date field is DateString. Is there an easy way to look up a parameter's declared type rather than its resolved type?

like image 604
Taytay Avatar asked Sep 06 '16 20:09

Taytay


1 Answers

Unfortunately this doesn't work because of "type interning." See here.

What works is to get the text of the typeNode. So basically get the text from the node. Here's a working example that you may be apply to your scenario:

// fileToAnalyze.ts
type DateString = string;
function myFunction(date: DateString) {
}

// main.ts
import * as ts from "typescript";
import * as path from "path";

const program = ts.createProgram([path.join(__dirname, "fileToAnalyze.ts")], { });
const file = program.getSourceFiles().filter(f => /fileToAnalyze/.test(f.fileName))[0];

const funcNode = (file.statements[1] as ts.FunctionDeclaration);
const parameterNode = funcNode.parameters[0];
console.log(parameterNode.type.getText(file)); // DateString

By the way, you might want to check out this library ts-type-info ts-simple-ast ts-morph that I've been working on in case you haven't seen it.

like image 66
David Sherret Avatar answered Nov 15 '22 08:11

David Sherret