Is there an API method to get the "bottomed out" type information from the TypeScript compiler? Example:
interface User {
id: number
name: string
}
type NameOnly = Pick<User, 'name'>
type NameOnlyAliased = NameOnly
In VSCode, if I hover over NameOnlyAliased
, it shows:
type NameOnlyAliased = {
name: string;
}
My question is if there is a function in the compiler API (or other simple way without applying the semantics of aliases, Pick
, etc.) to get the info on the right-hand side of the =
above, preferably as data (not just a string), something like:
{
NameAliasedOnly: {
properties: {
name: {
type: 'string'
}
}
}
}
The use-case is to generate code to create fast-check
arbitraries from type definitions (if that already exists, then fantastic). I've played around a bit with using ts-json-schema-generator
for this purpose, but there are some type definitions it doesn't handle.
I've found a solution. It doesn't use the TypeScript compiler API, directly, but rather the excellent ts-morph library, a wrapper for the compiler API which simplifies many tasks. Here's some example code, where the test.ts
file contains the example code from my question above.
import { Project, TypeFormatFlags } from 'ts-morph'
const project = new Project({
tsConfigFilePath: 'tsconfig.json',
skipAddingFilesFromTsConfig: true,
})
const file = 'test.ts'
project.addSourceFileAtPath(file)
const sourceFile = project.getSourceFile(file)
const typeAlias = sourceFile?.getTypeAlias('NameOnlyAliased')
if (typeAlias) {
console.log(
typeAlias
.getType()
.getProperties()
.map(p => [
p.getName(),
p
.getTypeAtLocation(typeAlias)
.getText(
undefined,
TypeFormatFlags.UseAliasDefinedOutsideCurrentScope
),
])
)
}
Executing this script gives output [ [ 'name', 'string' ] ]
, as desired. For more complex types you can navigate into the type hierarchy.