首页 > 解决方案 > 将 TypeScript 类型打印到控制台/文件中

问题描述

我有多种类型,它们构成了当前在我的服务器上使用的更大、更复杂的类型。是否可以将更大、更复杂的类型打印到控制台/文件中?

例子

type TypeA = {
  prop1: string;
  prop2: number;
}

type TypeB = Omit<TypeA, "prop2">;

console.logType(TypeB);
// {
//   prop1: string;
// }

标签: javascripttypescript

解决方案


为了提取类型签名,您需要使用编译器 API。假设你有一个文件:

// ./src/my-file.ts
type TypeA = {
  prop1: string;
  prop2: number;
}

type TypeB = Omit<TypeA, "prop2">;

从项目根目录外的脚本:

// ./type-printer.ts
import * as ts from "typescript";

function extractTypeSignature(filename: string, aliasName: string): string {

    const program: ts.Program = ts.createProgram([ filename ], { emitDeclarationOnly: true });
    const sourceFile: ts.SourceFile = program.getSourceFile(filename);
    const typeChecker: ts.TypeChecker = program.getTypeChecker();
    // Get the declaration node you're looking for by it's type name.
    // This condition can be adjusted to your needs
    const statement: ts.Statement | undefined = sourceFile.statements.find(
      (s) => ts.isTypeAliasDeclaration(s) && s.name.text === aliasName
    );
    if (!statement) {
        throw new Error(`Type: '${aliasName}' not found in file: '${filename}'`);
    }
    const type: ts.Type = typeChecker.getTypeAtLocation(statement);
    const fields: string[] = [];
    // Iterate over the `ts.Symbol`s representing Property Nodes of `ts.Type`
    for (const prop of type.getProperties()) {
        const name: string = prop.getName();
        const propType: ts.Type = typeChecker.getTypeOfSymbolAtLocation(prop, statement);
        const propTypeName: string = typeChecker.typeToString(propType);
        fields.push(`${name}: ${propTypeName};`);
    }
    return `type ${aliasName} = {\n  ${fields.join("\n  ")}\n}`;
}

const typeBSignature = extractTypeSignature("./src/my-file.ts", "TypeB");
// write to file or console log
console.log(typeBSignature);
/*
type TypeB = {
  prop1: string;
}
 */

我已经明确地注释了所有变量以显示类型的来源。即使它是一个小脚本,我还是建议使用 TypeScript 而不是 JavaScript 编写编译器脚本,并使用tsc file.ts && node file.js或使用类似ts-node的东西执行,因为类型推断/类型保护在导航编译器 API 时非常有用。


推荐阅读