Skip to content

Instantly share code, notes, and snippets.

@mfazekas
Created August 3, 2024 18:26
Show Gist options
  • Save mfazekas/70dda85b2eba1d9191684e91d41c053a to your computer and use it in GitHub Desktop.
Save mfazekas/70dda85b2eba1d9191684e91d41c053a to your computer and use it in GitHub Desktop.
Parse typescript types and generate code using ts-morph and ejs
import { Project } from 'ts-morph';
import ejs from 'ejs';
import type { Type, ts } from 'ts-morph';
import fs from 'fs';
const project = new Project();
let tamagui_root = "../tamagui";
project.addSourceFileAtPath(`${tamagui_root}/node_modules/@types/react/index.d.ts`);
const fileText = "import React from 'react' ; type JSXIntrinsicElements = JSX.IntrinsicElements;\n";
const sourceFile = project.createSourceFile("main.ts", fileText);
const typeAlias = sourceFile.getTypeAliasOrThrow('JSXIntrinsicElements');
console.log(typeAlias.getName()); // JSX.IntrinsicElements
// get the original type for the type alias and print it's members
const type = typeAlias.getType();
console.log(type.getText()); // JSX.IntrinsicElements
const properties = type.getProperties();
type TagType = 'svg' | 'html';
function getTagType(tag: string, tagType: Type<ts.Type>): TagType {
if (tagType.getText().match(/SVG.*Element/)) {
return 'svg';
} else {
return 'html';
}
}
const tags: { [tag in TagType]: string[] } = { svg: [], html: [] };
properties.forEach(property => {
const type = property.getValueDeclarationOrThrow().getType();// .getText()
const tagType = getTagType(property.getName(), type);
tags[tagType].push(property.getName());
//console.log(property.getName(), ' => ', type.getText());
//const typeproperties = type.getProperties();
//typeproperties.forEach(tp => {
// console.log(' ', tp.getName(), ' => ', tp.getValueDeclarationOrThrow().getType().getText());
//});
});
const outputFile = 'tags.ts';
ejs.renderFile('tags_simple.ts.ejs', { tags }, (err, str) => {
if (err) {
console.log('+> errr:', err);
} else {
//console.log(':> ', str);
fs.writeFileSync("./tags.ts", str, 'utf8');
}
});
<%_ const reserved = ['var', 'switch'] -%>
<%_ if (false) { -%>
const html = {
<%_ ['html', 'svg'].forEach(tag => { -%>
// <%= tag %>
<%_ tags[tag].forEach(property => { -%>
<%= property %>: html_tag('<%= property %>'),
<%_ }); -%>
<%_ }); -%>
} as const;
<%_ } else { -%>
<%_ ['html', 'svg'].forEach(tag => { -%>
// <%= tag %>
<%_ tags[tag].forEach(property => { -%>
<%_ if (reserved.includes(property)) { -%>
const <%= property %>_ = html_tag('<%= property %>');
export { <%= property %>_ as <%= property %> };
<%_ } else { -%>
export const <%= property %>= html_tag('<%= property %>');
<%_ } -%>
<%_ }); -%>
<%_ }); -%>
<%_ } -%>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment