Skip to content

Instantly share code, notes, and snippets.

@hasparus
Created October 23, 2019 20:48
Show Gist options
  • Save hasparus/20265c2f27d9ee136fa07500744ce703 to your computer and use it in GitHub Desktop.
Save hasparus/20265c2f27d9ee136fa07500744ce703 to your computer and use it in GitHub Desktop.
import * as ts from "typescript";
import { join } from "path";
import { readFileSync } from "fs";
// const source = `
// import React, { FC } from 'react'
// import { ReactThreeFiber } from './three-types'
// type Three = typeof import('three')
// type DefinedKeys<T extends object> = {
// [K in keyof T]-?: T[K] extends undefined ? never : K
// }[keyof T]
// type FilterDefined<T extends object> = Pick<T, DefinedKeys<T>>
// type ThreeFiberJsx = FilterDefined<
// {
// [P in keyof Three]: Three[P] extends Three['Object3D']
// ? FC<ReactThreeFiber.Object3DNode<InstanceType<Three[P]>, Three[P]>>
// : Three[P] extends Three['Geometry']
// ? FC<ReactThreeFiber.GeometryNode<InstanceType<Three[P]>, Three[P]>>
// : Three[P] extends Three['BufferGeometry']
// ? FC<ReactThreeFiber.BufferGeometryNode<InstanceType<Three[P]>, Three[P]>>
// : Three[P] extends Three['Material']
// ? FC<ReactThreeFiber.MaterialNode<InstanceType<Three[P]>, Required<ConstructorParameters<Three[P]>>>>
// : Three[P] extends new () => any
// ? FC<ReactThreeFiber.Node<InstanceType<Three[P]>, Three[P]>>
// : never
// }
// >
// `;
/**
* @template T
* @param {ts.Node} node
* @param {(n: ts.Node) => T[]} f
* @returns T[]
*/
const visit = (node, f) => {
const results = f(node);
node.forEachChild(child => {
results.push(...visit(child, f));
});
return results.filter(Boolean);
};
console.log({ __dirname });
const filePath = join(__dirname,
// 'src',
"/components.tsx");
const configFile = ts.findConfigFile(
__dirname,
ts.sys.fileExists,
"tsconfig.json"
);
const { config, error } = ts.parseConfigFileTextToJson(
configFile,
readFileSync(configFile, { encoding: "utf-8" })
);
if (error) {
console.error(error);
process.exit(1);
}
const options = ts.convertCompilerOptionsFromJson(config.compilerOptions);
const program = ts.createProgram([filePath], {
...options,
baseUrl: '..',
jsx: ts.JsxEmit.React
});
const sourceFile = program.getSourceFile(filePath);
const typeChecker = program.getTypeChecker();
if (!sourceFile) {
console.error("Can't find source file", filePath)
}
console.log(sourceFile !== undefined);
console.log(
visit(sourceFile, node => {
if (!node) {
return [];
}
if (node.kind === ts.SyntaxKind.TypeAliasDeclaration) {
/** @type {ts.TypeAliasDeclaration} */
const declaration = node;
if (declaration.name.escapedText === 'ThreeFiberJsx') {
return typeChecker.getTypeAtLocation(declaration).getProperties().map(symbol => symbol.escapedName);
}
}
return [];
})
);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment