type-graphql
type-graphql copied to clipboard
Decorate constructor arguments with access modifiers
Is your feature request related to a problem? Please describe. We are using extensively cool TypeScript feature which allows parameters from constructor map to class members, Example:
export class User {
constructor(
public id: number,
public username: string,
) { }
}
then
let admin = new User(1,'admin');
console.log(admin.id) // prints 1
Describe the solution you'd like I would like to be able to decorate these parameters as well
Describe alternatives you've considered Don't use this TS feature
For now, @Field()
is a MethodAndPropDecorator
, so you can't do that.
While it's possible to add support for parameters in constructor, it's an error prone pattern as you can easily missplace the parameter and swap mobilePhone
with homePhone
, age with balance and others.
If you really want to create a class instance, it's better to accept the anonymous object in constructor and call Object.assign
inside of it.
it's an error prone pattern
every pattern can be missused, but there are a lot of use cases where object types have very few arguments, or are constructed by a factory or builder pattern.
just to have an example for a valid use case:
@InterfaceType()
abstract class UpdateUserResult {
public constructor(
@Field(() => User)
public readonly user: User,
) {}
}
@ObjectType({ implements: UpdateUserResult })
class UpdateUserResultOk extends UpdateUserResult {}
@ObjectType({ implements: UpdateUserResult })
class UpdateUserResultRejected extends UpdateUserResult {
public constructor(
user: User,
@Field(() => String)
public readonly reason: string,
) {
super(user);
}
}
Should be fairly easy to implement, moving to 1.x
release milestone 👀
this feature is very welcome to easily form up responses in queries mutations etc
Any progress on this? Quality of Life feature :)
I've checked and unfortunately this is not possible 😞 https://www.typescriptlang.org/docs/handbook/release-notes/typescript-5-0.html#more-accurate-type-checking-for-parameter-decorators-in-constructors-under---experimentaldecorators
When using decorator on constructor argument, it's treated like a function parameter decorator.
So we have no propertyKey
information, only the parameter index.
So we can't make it working easily.
The only solution would be to duplicate the property name in the decorator options:
@ObjectType()
export class User {
constructor(
@Field(() => Int, { propertyName: "id" })
public id: number,
@Field({ propertyName: "username" })
public username: string,
) { }
}
Which makes no sense, it's same duplication like now with defining constructor params apart from the fields definitions.