openapi-ts / openapi-typescript

Generate TypeScript types from OpenAPI 3 specs
https://openapi-ts.dev
MIT License
5.05k stars 408 forks source link

[v7] transform + nullable issue with Identifier with Node.js API #1688

Closed depsimon closed 1 day ago

depsimon commented 1 month ago

Description

I'm trying to use the docs example to transform the schema for Date & Blobs.

[{
    "resource": "/Users/simon/Code/WebApp/packages/sdk/openapi.ts",
    "owner": "typescript",
    "code": "2322",
    "severity": 8,
    "message": "Type '(schemaObject: SchemaObject) => Identifier | UnionTypeNode | undefined' is not assignable to type '(schemaObject: SchemaObject, options: TransformNodeOptions) => TypeNode | TransformObject | undefined'.\n  Type 'Identifier | UnionTypeNode | undefined' is not assignable to type 'TypeNode | TransformObject | undefined'.\n    Type 'Identifier' is not assignable to type 'TypeNode | TransformObject | undefined'.\n      Type 'Identifier' is not assignable to type 'TypeNode'.",
    "source": "ts",
    "startLineNumber": 12,
    "startColumn": 5,
    "endLineNumber": 12,
    "endColumn": 14
},{
    "resource": "/Users/simon/Code/WebApp/packages/sdk/openapi.ts",
    "owner": "typescript",
    "code": "2741",
    "severity": 8,
    "message": "Property '_typeNodeBrand' is missing in type 'Identifier' but required in type 'TypeNode'.",
    "source": "ts",
    "startLineNumber": 15,
    "startColumn": 45,
    "endLineNumber": 15,
    "endColumn": 49,
    "relatedInformation": [
        {
            "startLineNumber": 5204,
            "startColumn": 9,
            "endLineNumber": 5204,
            "endColumn": 23,
            "message": "'_typeNodeBrand' is declared here.",
            "resource": "/Users/simon/Code/WebApp/node_modules/.pnpm/typescript@5.4.5/node_modules/typescript/lib/typescript.d.ts"
        }
    ]
},{
    "resource": "/Users/simon/Code/WebApp/packages/sdk/openapi.ts",
    "owner": "typescript",
    "code": "2322",
    "severity": 8,
    "message": "Type 'Identifier' is not assignable to type 'TypeNode'.",
    "source": "ts",
    "startLineNumber": 20,
    "startColumn": 45,
    "endLineNumber": 20,
    "endColumn": 49
}]
Name Version
openapi-typescript 7.0.0-rc.0
Node.js v20.11.1
Typescript v5.5.5
OS + version macOS 14.5

Reproduction

Here's my TS file I'm using to generate my SDK:

import fs from "node:fs";
import openapiTS, { astToString } from "openapi-typescript";
import ts from "typescript";

const BLOB = ts.factory.createIdentifier("Blob"); // `Blob`
const DATE = ts.factory.createIdentifier("Date"); // `Date`
const NULL = ts.factory.createLiteralTypeNode(ts.factory.createNull()); // `null`

const ast = await openapiTS(
  new URL(mySchema),
  {
    transform(schemaObject) {
      if (schemaObject.format === "date-time") {
        return schemaObject.nullable
          ? ts.factory.createUnionTypeNode([DATE, NULL])
          : DATE;
      }
      if (schemaObject.format === "binary") {
        return schemaObject.nullable
          ? ts.factory.createUnionTypeNode([BLOB, NULL])
          : BLOB;
      }
    },
  },
);

const contents = astToString(ast);
fs.writeFileSync("./src/api.ts", contents);

Expected result

No Typescript errors.

Checklist

ziyuang commented 3 weeks ago

Do you think this is related: https://github.com/microsoft/TypeScript/issues/40263

Flax95 commented 1 week ago

Did you manage to solve this? 🙂 I ran into the same problem when following the docs example.

depsimon commented 1 week ago

Nope, I'm not using this at the moment.

danmichaelo commented 1 day ago

Seems to work to wrap the Identifiers in ts.factory.createTypeReferenceNode:

const BLOB = ts.factory.createTypeReferenceNode(ts.factory.createIdentifier("Blob"));
const FILE = ts.factory.createTypeReferenceNode(ts.factory.createIdentifier("File"));
const NULL = ts.factory.createLiteralTypeNode(ts.factory.createNull());

Btw. I found out by using the TypeScript AST Viewer, where you can type in some TypeScript and see the factory method calls needed to generate that TypeScript: https://ts-ast-viewer.com/#code/C4TwDgpgBMEM7CgXigMQJYBsIB8B2ArppkA

image

drwpow commented 1 day ago

Btw. I found out by using the TypeScript AST Viewer, where you can type in some TypeScript and see the factory method calls needed to generate that TypeScript: https://ts-ast-viewer.com/#code/C4TwDgpgBMEM7CgXigMQJYBsIB8B2ArppkA

Oh I hadn’t seen that website before! That’s very handy! Bookmarking it.