babel typescript interface convert to variable

134 Views Asked by At

There is Props interface from third-party:

interface Props {
  id: string;
  name: string;
  age: number;
  approval: Approval
}

interface Approval {
  signature: string;
}

What is the solution that Props convert to array:

[
  {
    name: 'id',
    type: 'string'
  },
  {
    name: 'name',
    type:'string'
  },
  {
    name: 'age',
    type: 'number'
  },
  {
    name: 'approval',
    type: 'Approval'
  }
]

I have no idea that Typescript's interface can do this?

Update: Maybe it is not 'convert', somehow it just like 'reflect' or something else. Can I do this in babel?

However, I just want to get this array by Props.

1

There are 1 best solutions below

0
riskers On

Finally, I solved this problem through TS Compile API:


const {Project, SyntaxKind, Node, PropertySignature} = require('ts-morph');
const {resolve, dirname} = require('path');

    let res = {
        "Msg": [{
            "type": "string",
            "name": "type"
        }]
    }
    const project = new Project()
    project.addSourceFileAtPath(sourceFilePath)
    const sourceFile = project.getSourceFile(sourceFilePath)

    const msgInterfaces = sourceFile.getInterfaces()
        .filter((interfaceDecl) => {
            const interfaceName = interfaceDecl.getName()
            return interfaceName.endsWith("SDKType") && !interfaceName.includes("Response")
        })

    for (const msgInterface of msgInterfaces) {
        console.log(sourceFilePath, msgInterface.getName(), 'is building')

        const properties = msgInterface.getProperties()

        for (const property of properties) {
            const propStructure = property.getStructure()

            let name = propStructure.name
            let type = propStructure.type;

            if (BASIC_MSG_EIP712_TYPES[type]) {
                res["Msg"].push({
                    type: BASIC_MSG_EIP712_TYPES[type],
                    name,
                })
                continue
            }

            if (property.getType().isEnum()) {
                type = "string"
                res["Msg"].push({
                    type,
                    name,
                })
                continue;
            }

            if (property.getType().isArray()) {
                const ele = property.getType().getArrayElementType().getText()
                if (!Object.keys(BASIC_MSG_EIP712_TYPES).includes(ele)) continue;

                type = BASIC_MSG_EIP712_TYPES[ele] + "[]"
                res["Msg"].push({
                    type,
                    name
                })
                continue
            }

            if (property.getType().getSymbol().getDeclarations()[0].getKind() === SyntaxKind.InterfaceDeclaration) {
                type = "Type" + upperCaseFirst(snakeToCamel(name))
                res["Msg"].push({
                    type,
                    name,
                })

                const pps = property.getType().getProperties()
                res[type] = pps.map(p => {
                    return {
                        type: p.getValueDeclaration().getType().getText(),
                        name: p.getName(),
                    }
                })
                continue;
            }
        }

        project.createSourceFile(
            `./${dirname(filePath)}/${msgInterface.getName()}EIP712.ts`,
            `export const ${msgInterface.getName()}EIP712 = ${JSON.stringify(res, null, 2)} \n\n`,
            {overwrite: true}
        )
        project.saveSync()
    }