I am working with NestJs and Typescript 4.7.4. I am having an issue when Architecture team decide to update tsconfig
like this
compilerOptions: {
"target": "es2020",
...
}
to
compilerOptions: {
"target": "es2023",
"moduleDetection": "force", // add more
"isolatedModules": true, // add more
"useDefineForClassFields": true, // add more
"allowJs": true, // add more
"forceConsistentCasingInFileNames": true, // add more
"skipLibCheck": true // add more
}
Now, all my Decorators like @HttpCode(200)
or @Controller(SomeClass.url)
build failed with this error
TS1241: Unable to resolve signature of method decorator when called as an expression.
TS1270: Decorator function return type void | TypedPropertyDescriptor<unknown> is not assignable to type void | TypedPropertyDescriptor<(body: SomeClassBodyDto) => Promise<SomeClassResponseDto>>
I have searched for similar errors, but they always lead to some solutions that need to
change tsconfig
or using some flag when ts build without any explanation why or at least it too short to understand in-depth.
I want to ask what happen, why my decorators complain about these errors and how to resolve it without touch any tsconfig?
I am working with NestJs and Typescript 4.7.4. I am having an issue when Architecture team decide to update tsconfig
like this
compilerOptions: {
"target": "es2020",
...
}
to
compilerOptions: {
"target": "es2023",
"moduleDetection": "force", // add more
"isolatedModules": true, // add more
"useDefineForClassFields": true, // add more
"allowJs": true, // add more
"forceConsistentCasingInFileNames": true, // add more
"skipLibCheck": true // add more
}
Now, all my Decorators like @HttpCode(200)
or @Controller(SomeClass.url)
build failed with this error
TS1241: Unable to resolve signature of method decorator when called as an expression.
TS1270: Decorator function return type void | TypedPropertyDescriptor<unknown> is not assignable to type void | TypedPropertyDescriptor<(body: SomeClassBodyDto) => Promise<SomeClassResponseDto>>
I have searched for similar errors, but they always lead to some solutions that need to
change tsconfig
or using some flag when ts build without any explanation why or at least it too short to understand in-depth.
I want to ask what happen, why my decorators complain about these errors and how to resolve it without touch any tsconfig?
Share Improve this question asked 5 hours ago naPhamnaPham 231 silver badge3 bronze badges1 Answer
Reset to default 0It seems like the problem is caused by useDefineForClassFields: true
. It changes how class fields are initialised. Instead of using assignment this.property = value
, it uses Object.defineProperty
.
Before:
class SomeClass {
someProperty = "value";
}
After:
class SomeClass {
someProperty;
constructor() {
Object.defineProperty(this, "someProperty", { value: "value", writable: true, configurable: true });
}
}
NestJS relies heavily on TypeScript's experimental decorator implementation and it seems that it isn't fully compatible with the new realisation and the metadata attached to methods is not resolving correctly.
This is the attempt to answer the question of what happened.
But I'm not sure is there is a good solution on how to fix it without disabling useDefineForClassFields
. It might help to try explicitly defining your controller method types but even if it will work, the solution is far from the ideal. Perhaps, it would be best to consult with your Architecture team and make sure they know about this problem and took it into account when they changed tsconfig
.
Also, here is the GitHub issue comment on how useDefineForClassFields
works that you might find useful.