最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Print TypeScript types into consolefile - Stack Overflow

programmeradmin4浏览0评论

I have multiple types that form a larger, plex type that currently is used on my server. Is it possible to print the larger, plex type into console / file?

Example

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

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

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

I have multiple types that form a larger, plex type that currently is used on my server. Is it possible to print the larger, plex type into console / file?

Example

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

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

console.logType(TypeB);
// {
//   prop1: string;
// }
Share Improve this question edited Jul 7, 2021 at 12:08 Peter Mortensen 31.6k22 gold badges110 silver badges133 bronze badges asked Apr 22, 2021 at 23:55 SILENTSILENT 4,2687 gold badges41 silver badges65 bronze badges 5
  • Just console.log("value_you_want_to_see"); – hoangdv Commented Apr 23, 2021 at 1:37
  • 1 @hoangdv That doesn't work for typescript types (ie type Something = Boolean) – SILENT Commented Apr 23, 2021 at 3:45
  • 2 Types don't exist at runtime. If you want to print out a type, you'll need to use the typescript piler API, and then it will be very dependent on what you're trying to extract. Do you want the type of a value, the properties of an intersection, etc.? Can you give an example of what you're trying to print? – chrisbajorin Commented Apr 23, 2021 at 15:33
  • @chrisbajorin Updated with an example. I just need to export the Typescript files for use elsewhere. In my situation, the typescript types are generated by 3rd party library jsonschema-definer – SILENT Commented Apr 23, 2021 at 17:10
  • Types (used by TypeScript) are Compile-Time. Values (used by console.log) are Run-Time. If you want something that covers both, you can use this trick: stackoverflow./a/59806829/2321594 – Aidin Commented Dec 2, 2023 at 23:22
Add a ment  | 

3 Answers 3

Reset to default 13

In order to extract the type signature, you'll need to use the piler API. Assuming you have a file:

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

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

from a script outside your project root:

// ./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;
}
 */

I've explicitly annotated all variables to show where the types are ing from. Even though it's a small script, I'd remend writing piler scripts in TypeScript rather than JavaScript and executing with tsc file.ts && node file.js or using something like ts-node, as the type inference/typeguards are very useful when navigating the piler API.

Good IDEs, like WebStorm, will show you a new type:

If you want to omit some types that you will be going to share with a third party then you will need to use @internal:

type First = {
  propA: string
  /** @internal */
  propB: number
}

And use stripInternal flag in the configuration when you will generate the .d.ts file.

{
  "include": ["aaa/**/*"],
  "pilerOptions": {
    "declaration": true,
    "emitDeclarationOnly": true,
    "outDir": "dist",
    "stripInternal": true
  }
}
发布评论

评论列表(0)

  1. 暂无评论