title: What is the best practice about DTO, schema or interface for typing in typescript
body: <p>Currently in my typescript code (nestjs) I use the DTO in my controller to validate the data that goes into my API, the schemas are used as type in the rest of the files and I do not create an interface except in special cases.</p>
  <p>I'm trying to figure out if what I'm doing is good or if I should use the DTO as a type everywhere, or something? The goal is to increase the quality of my code.</p>
  <p>Example with the user collection:</p>
  <p><code>user.schema.ts</code></p>
  <pre><code>import { Prop, Schema, SchemaFactory } from '@nestjs/mongoose';
  import { Document } from 'mongoose';
  
  @Schema({ collection: 'users' })
  export class User extends Document {
    @Prop()
    name: string;
  }
  
  export const UserSchema = SchemaFactory.createForClass(User);
  UserSchema.set('timestamps', true);
  </code></pre>
  <p><code>user.dto.ts</code></p>
  <pre><code>import { IsNotEmpty, IsString, Length } from 'class-validator';
  import { ApiProperty } from '@nestjs/swagger';
  
  export class UserDto {
    @IsNotEmpty()
    @IsString()
    @Length(3)
    @ApiProperty({ required: true })
    readonly name: string;
  }
  </code></pre>
  <p>Example of use :</p>
  <ul>
  <li>in a controller with the dto</li>
  </ul>
  <pre><code>async createUser(@Body() user: UserDto): Promise&lt;UserSchema&gt; {
    const nameAlreadyExist = await this.userService.getUserByField('name', user.name);
    if (nameAlreadyExist &amp;&amp; nameAlreadyExist.length &gt; 0) {
      throw new ConflictException(getErrorObject(ErrorCodeEnum.duplicate, EntityCodeEnum.user, ['name']));
    }
    return this.userService.createUser(user as UserSchema);
  }
  </code></pre>
  <ul>
  <li>in the service with the schema</li>
  </ul>
  <pre><code>async createUser(user: UserSchema): Promise&lt;UserSchema&gt; {
    const newUser = new this.UserModel(user);
    return newUser.save();
  }
  </code></pre>