tsoa icon indicating copy to clipboard operation
tsoa copied to clipboard

Nullable information is lost with Typescript Utility Type (Pick, Partial, ...)

Open bigen1925 opened this issue 8 months ago • 3 comments

Sorting

  • I'm submitting a ...

    • [x] bug report
    • [ ] feature request
    • [ ] support request
  • I confirm that I

    • [x] used the search to make sure that a similar issue hasn't already been submit

Expected Behavior

{
    "schemas": {
      "Partial__nullableString-string-or-null__": {
        "properties": {
          "nullableString": {
            "type": "string",
            "nullable": true  #### nullable should be included
          }
        },
        "type": "object",
        "description": "Make all properties in T optional"
      },
      "ReturnType": {
        "$ref": "#/components/schemas/Partial__nullableString-string-or-null__"
      }
    },
}

Current Behavior

{
    "schemas": {
      "Partial__nullableString-string-or-null__": {
        "properties": {
          "nullableString": {
            "type": "string"  #### nullable is not included
          }
        },
        "type": "object",
        "description": "Make all properties in T optional"
      },
      "ReturnType": {
        "$ref": "#/components/schemas/Partial__nullableString-string-or-null__"
      }
    },
}

Possible Solution

make nullable information not to be lost

Steps to Reproduce

  1. with Controller
import { Controller, Get, Route } from "tsoa";

type ReturnType = Partial<{ nullableString: string | null }>;

@Route("sample")
export class SampleController extends Controller {
  @Get()
  getSample(): ReturnType {
    return {} as any;
  }
}
  1. npx tsoa spec

Context (Environment)

Version of the library: [email protected] Version of NodeJS: v18.15.0

  • Confirm you were using yarn not npm: [x]

Detailed Description

Thank you in advance for your development and maintenance for this awesome framework! I love and use in production this :)

I confirmed that nullable is lost when defining types with Pick and Partial and Exclude.

This didn't happen (nullable is NOT lost) in [email protected].

Please let me know if I can provide any more information.

Breaking change?

NO

bigen1925 avatar Nov 25 '23 22:11 bigen1925

I have also ran into this issue! I upgraded from 5.1.1 to this 6.0.0-rc.5 in order to fix this issue with Omit and PIck: https://github.com/lukeautry/tsoa/issues/1238, and now am losing the nullable in the generated swagger

gcv-epalmer avatar Dec 06 '23 14:12 gcv-epalmer

I created a failing unit test for this: https://github.com/gcv-epalmer/tsoa-test

Tried my hand at fixing the bug but I think I'm a bit over my head. My best guess is that the TypeResolver doesn't play super nicely with reference/mapped types

gcv-epalmer avatar Dec 06 '23 22:12 gcv-epalmer

I also encountered this issue while bumping tsoa from 5.1.1 to 6.0.0, I confirm that I lost the nullable attribute while using Partial alias in TypeScript:

export default interface UserInsertionBody {
    username: string
    password: string
    roles?: { roleName: ROLE_NAME; siteId: string | null }[]
    preferences?: UserPreferences | null
}

I lose nullable in both roles.siteId and preferences attributes when using Partial<UserInsertionBody>. Thank you @bigen1925 and @gcv-epalmer for pointing it out!

mch-outsight avatar Jan 05 '24 10:01 mch-outsight

Encountered this as well, attempted to fix it by taking a 4 hour deep dive into this library's internals & typescript AST, and noted the fact that if you enable strictNullChecks in tsoa's compilerOptions, this stats working again.

Noteworthy however is that with strictNullChecks enabled, some of tsoa's test suite fails, when I tested just applying that by default in the library itself.

iffa avatar Feb 06 '24 13:02 iffa

Are there any updates on this? I'd like to get rid of the any types I am forced to use across the app because the validators won't allow nullables of any type.

PavelSarlov avatar Apr 17 '24 07:04 PavelSarlov

Up.

Issue with body validation and Partial as described here: https://github.com/lukeautry/tsoa/issues/1612

Fixed thanks to @iffa with strictNullChecks

JoranLive avatar Jun 21 '24 14:06 JoranLive

@JoranLive, could you explain how is this fixed? I'm having the same issue. I define a property like:

titleTag?: string | null;

But when passing null to it, TSOA throws:

'locations.$0.titleTag': { message: 'invalid string value', value: null }

Thanks!

vedtam avatar Jul 01 '24 11:07 vedtam

@vedtam , the workaround is adding "strictNullChecks": true under compilerOptions at tsoa config file

dsambugaro avatar Jul 01 '24 12:07 dsambugaro

@dsambugaro thanks, but compilerOptions aren't taken from tsconfig.json? I have the flag "strictNullChecks" set there, and been having the issue still.

vedtam avatar Jul 01 '24 12:07 vedtam

@vedtam the tsoa.json also accepts the compilerOptions. I'm unsure if tsoa takes compilerOptions from tsconfig.json, or if it has some bug on this behavior since it was only "fixed" when I explicitly set it on tsoa.json. It is working for me until now

{
  "spec": {
    ...
  },
  "routes": {
    ...
  },
   "compilerOptions": {
        "strictNullChecks": true,
    }
}

dsambugaro avatar Jul 01 '24 14:07 dsambugaro

@dsambugaro got it, thanks!

vedtam avatar Jul 01 '24 14:07 vedtam