Search code examples
node.jstypescriptreflectionannotations

List properties and types of a class


Is there a way in TypeScript, maybe a post-processor, transformer, reflection API or annotation system to get the properties of a class and the types of the property, like Python's __annotations__?

This is what I want in code:

class A {
   public k: string;
   public o: number;
   public s: AnotherClass;
}

sometool(A); // And get something like:

{
  k: String,
  o: Number,
  s: AnotherClass
} 


Solution

  • As Wiktor Z. mentioned in the comment, typeconv seems like a good option for specific task.

    But if you are looking for something more general with more possibilities, a reflection is the right direction. Unfortunately TypeScript iself does not contain anything even close to the reflection but some smart people created reflection for TS. You can use one of the solutions mentioned in this repo typescript needs types.

    I'm author of one of those solutions for TypeScript runtime reflection. Here is a Stackblitz example for your use-case.

    import { Type } from 'rttist';
    import { Metadata } from './metadata.typelib';
    
    printSchemas([
        ...Metadata.getTypes().filter((t) => t.module.id.includes('/models/Model')),
    ]);
    
    function printSchemas(types: Type[]) {
        for (let t of types) {
            console.log(t.displayName);
    
            if (!t.isObjectLike()) {
                throw new Error(`Non-object type: ${t.displayName}`);
            }
    
            const schema = t.getProperties().reduce((obj, prop) => {
                if (prop.name.isString()) {
                    obj[prop.name.name] = prop.type.isPrimitive()
                        ? prop.type.name
                        : prop.type.id;
                }
                return obj;
            }, {} as Record<string, string>);
    
            console.table(schema);
        }
    }
    

    Output

    Interface IModelOne [@rttist-esbuild-demo/models/ModelOne:IModelOne]
    ┌─────────┬──────────┐
    │ (index) │  Values  │
    ├─────────┼──────────┤
    │   foo   │ 'String' │
    │   bar   │ 'Number' │
    └─────────┴──────────┘
    Class ModelThree [@rttist-esbuild-demo/models/ModelThree:ModelThree]
    ┌─────────┬─────────────────────────────────────────────────┐
    │ (index) │                     Values                      │
    ├─────────┼─────────────────────────────────────────────────┤
    │   foo   │                    'String'                     │
    │   bar   │                    'Number'                     │
    │   baz   │ '@rttist-esbuild-demo/models/ModelTwo:ModelTwo' │
    └─────────┴─────────────────────────────────────────────────┘
    Class ModelTwo [@rttist-esbuild-demo/models/ModelTwo:ModelTwo]
    ┌─────────┬───────────┐
    │ (index) │  Values   │
    ├─────────┼───────────┤
    │  alfa   │ 'Boolean' │
    │  bravo  │  '#Date'  │
    └─────────┴───────────┘