So far so good with this library, but now that I'm trying to make well defined models using Partial and Pick, I'm hitting quite a bit of issues with the tsoa generator.
For instance, I have a model:
/**
* @tsoaModel
*/
export interface Environment {
id: number;
name: string;
username: string;
created: Date;
updated?: Date;
}
And do not want id, created, or updated to show up in the CREATE request. These are fulfilled by the database, not the user. I searched in this repo for omit, ignore, or exclude and found no information about flagging properties.
So I decided to go the TypeScript-way, and use Pick. So I have a type that looks like:
export type NewEnvironment = Pick<Environment, 'name' | 'username'>;
Which results in an empty object as the template in Swagger. This isn't ideal. Is there a solution to support a well formed base model, that allows flexibility when creating/updating?
Thanks in advance.
probably related to #210 and #204
My personal approach has been to have a separate create model and a return model. This resembles the approach recommended by TypeOrm.
// src/models/environmentModels
/**
* @tsoaModel
*/
export interface IEnvironmentCreateRequest {
name: string;
username: string;
}
/**
* @tsoaModel
*/
export interface IEnvironmentResponse extends IEnvironmentCreateRequest {
id: number;
created: Date;
updated?: Date;
}
And then you can use it in your route like this:
import { Get, Post, Route, Body, Query, Header, Path, SuccessResponse, Controller } from 'tsoa';
import * as httpStatusCodes from 'http-status-codes';
import { IEnvironmentCreateRequest, IEnvironmentResponse } from './environmentModels';
@Route('environment')
export class EnvironmentController extends Controller {
@Get('{environmentId}')
public async getEnvironmentById(environmentId: number): Promise<IEnvironmentResponse> {
// ...
}
@Post()
public async createEnvironment(@Body() newEnvironment: IEnvironmentCreateRequest): Promise<IEnvironmentResponse> {
// ...
}
}
I realize that this doesn't solve issue https://github.com/lukeautry/tsoa/issues/210 but it is a very sturdy workaround for this particular issue. It's actually how I would recommend writing your code so you don't have type aliases all over the code base. Because as you can see in the snippet above, it's nice and clean to have two separate interface names. Yes, I realize that you could also accomplish this with a type alias (but that will get solved when https://github.com/lukeautry/tsoa/issues/204 is solved).
Hopefully this helps future readers. Best of luck! :)
Most helpful comment
probably related to #210 and #204