I am trying to use the Typescript API to get information from typescript file that imports types from other sources.
I got common type:
// example.types.ts
export interface Example<T> {
description: string;
title: string;
element: T;
}
Then some element component or class I want to prepare example for
// Canvas.ts
interface ICanvasConfig {
name: string;
size: {
width: number;
height: number;
};
}
export const Canvas = (config: ICanvasConfig): void => {
console.log(config);
};
And this is the target file I want to parse
// Canvas.example.ts
import type { Example } from './example.types';
import { Canvas } from './Canvas';
const exampleMeta: Example<typeof Canvas> = {
title: 'Canvas Element',
description: 'Element used for..',
element: Canvas
};
export default exampleMeta;
What I'm expecting is to get at the end something like
{
title: {
value: 'Canvas Element',
type: 'string'
}
description: {
value: 'Element used for..',
type: 'string',
},
element: {
value: Canvas, // real value
type: {
name: 'function',
args: [{
name: 'string',
size: {
width: 'number',
height: 'number'
}
}],
ret: 'void'
}
}
}
I tried to use ts compiler and ts-morph but all I do is beating around the bush.
I wont publish my solution attempts not to distract you, but it seems I don't understand the inner structure of ts nodes to get what I need. Maximum what I got playing around is detecting title, description as a string but any type for element.
So my question is it actually possible using these tools? If yes then how? Are there any better solutions to achieve what I need?
Or if you ever faced with similar problems sharing your experience would be much appreciated.
You can achieve that using ts-morph with the code below. This code only works for the example code you provided, but it should be easy to implement a more generic solution using recursion.
I also found a related GitHub issue "Question: Is there a simple way to get a type reduced to only primitives?" and it has a library for expanding types https://github.com/dsherret/ts-morph/issues/1204#issuecomment-961546054, although it does not extract values such as 'Canvas Element'. To use that add
type exampleMeta = typeof exampleMetatoCanvas.example.tsand runimport { typeFootprint } from "./typeFootprint"; console.log(typeFootprint("src/Canvas.example.ts", "exampleMeta"));to get the string *1.*1