I have 3 classes as follows:
class Server {
@Expose({ name: 'APP_PORT' })
@Type(() => Number)
port: number
@Expose({ name: 'APP_TAG' })
@Type(() => String)
tag: string
}
class Database {
@Expose({ name: 'DATABASE_PORT' })
@Type(() => Number)
port: number
@Expose({ name: 'DATABASE_NAME' })
@Type(() => String)
name: string
}
class Global {
@Type(() => Server)
server: Server
@Type(() => Database)
database: Database
}
I will convert the plainObject
below into instance
with the following code:
import { plainToInstance } from 'class-transformer'
const plainObject = {
APP_PORT: 5000,
APP_TAG: '1.0.1',
DATABASE_PORT: 8000,
DATABASE_NAME: 'test',
}
const instance = plainToInstance(Global, plainObject)
console.log(instance)
The returned result is as follows:
Global {
server: undefined,
database: undefined,
APP_PORT: 5000,
APP_TAG: '1.0.1',
DATABASE_PORT: 8000,
DATABASE_NAME: 'test',
}
It is not what I expected. I want it to be like this:
Global {
server: {
APP_PORT: 5000,
APP_TAG: '1.0.1',
},
database: {
DATABASE_PORT: 8000,
DATABASE_NAME: 'test',
},
}
What adjustments do I need to make to the 3 classes above
to achieve what I want ?
Additional information is that I temporarily solved it by changing the plainObject
to the following:
const plainObject = {
server: {
APP_PORT: 5000,
APP_TAG: '1.0.1',
},
database: {
DATABASE_PORT: 8000,
DATABASE_NAME: 'test',
},
}
But it is not a "pure" decorator approach.
Finally, I found a solution that seems to work. Just need to add these few lines to the Global
class:
class Global {
// --------------Add this lines-------------- //
@Expose({ name: 'APP_TAG' })
@Transform(({ obj }) =>
plainToInstance(Server, obj, { excludeExtraneousValues: true }),
)
// ------------------------------------------ //
@Type(() => Server)
server?: Server
// --------------Add this lines-------------- //
@Expose({ name: 'DATABASE_NAME' })
@Transform(({ obj }) =>
plainToInstance(Database, obj, { excludeExtraneousValues: true }),
)
// ------------------------------------------ //
@Type(() => Database)
database?: Database
}