swc
swc copied to clipboard
Drop constructor() if it contains only super() with same arguments
Describe the feature
I have a extends Error
class, but how TypeScript defines cause
as unknown
, I need just rewrite constructor()
to set cause
type as I expect. But when it is transformed into JavaScript, so it can be just dropped.
export class GenericError extends Error {
public cause!: { value: number };
public constructor(
message: string,
cause: { value: number }
) {
super(message, cause);
}
}
So, I can do that, with TS validation to number
for cause
:
throw new GenericError("message", { cause: 123 });
It is just transformed into (pretty-printed):
export class GenericError extends Error{
cause;
constructor(r,e) {
super(r,e)
}
}
Once constructor()
just calls super()
with the same args, so I think it can be safetly dropped.
https://play.swc.rs/?version=1.3.55&code=H4sIAAAAAAAAA22NQQqDMBBF94J3%2BN0peAJdl54jpoMEYhJmMkUQ796k6aKLLuf9%2F9%2FQkSJnWG9E8KBA7OydOTLoyBSegnadfQckXb2zsEaFbjNOvIxXmhF0X4lxLX33W4tBMqvNkYeKgZ1EzFYGhbuwTY1%2BdH9sNR3bY0A0EQ9fwdQ241Kz0rveS6BdBMYAAAA%3D&config=H4sIAAAAAAAAA41VwW7bMAy99ysCn3fochiGfkBv%2BwZBsShHnSwaIuUmKPLvoxU7TRva2CWI%2BfRIkXykPp52u%2BaN2uZl9yF%2F5WOwmSDfvsVC58T2JJaGzwNQm8PAzY8FZZogbyNBNV2uSMM2d8ATC2j%2FvN%2FPjCYiEiyM2daHFPz5PmaL%2FZCB6M4mVnFZekhMX%2FkzlvF9AjiXe%2FsBMYJNG4ixZEJi6CBrjluM0Q4EZrRZ8TLd1OZAqIWYwMLgzJBxUPHkAgdMEvMRdWCdadGBAoUMLYcRNJrEEloiSU%2FJp8IODqXrap%2B%2FsWG0sVhWYsKptkRuq3g9YiA2viSthFdwpQZXcC7ud2bwJgOXnB55bxjSSk%2F%2BAkgFoiVKtgfNbz3hRU9rbL%2FJDMmLZPms4KJvLcsEnRTVhOCVyk6VgcxB62YGV1qYKttq15nhlfJRcGDAe9GK4preA7dHLeg06OgVQPprvaaqK2BuU7iCTwOxAb9KlqwLbD7RWz6uo3TuDxg3AvTAR3QbB6QVjOtwli1xGtbxkhyINMCpRwpV4HEJyAAwmlj35YM2ZDzEo%2BkiHj7XxHzgctvDvU1dnfe7fck4RBghrsn4P0ZkE5W7jZOql8l%2BmF74rYnSyuCFn89fng1J5Wn5rUk1Pbpyl1DV5PU5%2BdV8HlpejqVqTaA%2FC7HW6fIP6MYcrOMGAAA%3D
https://github.com/microsoft/TypeScript/issues/54021
Babel plugin or link to the feature description
No response
Additional context
No response
I don't expect this to have meaningful difference in real-world apps.
@kdy1 I found a lot of real-world examples based on same concept: to strong typing.
- https://grep.app/search?q=constructor%5Cs%2A%5C%28.%2B%5C%29%5Cs%2A%5C%7B%5Cs%2Asuper%5C%28.%2B%5C%29%5Cs%2A%3B%5Cs%2A%7D®exp=true&filter[lang][0]=TypeScript
And if you come to reconsider this case, perhaps this can be applied under the same condition for parent methods:
class GenericLog {
public log(info: any) {
console.log(info);
}
}
class NumberLog extends GenericLog {
public log(info: number) {
return super.log(info);
}
}
const genericLog = new GenericLog();
genericLog.log(123); // Nice
genericLog.log('error'); // Nice
const numberLog = new NumberLog();
numberLog.log(123); // Nice
numberLog.log('error'); // Bad (because it was narrowed)
There are also cases where there will be no return
, but the rule can only be applied if the parent method also doesn't return
a value (as it's a more complex case, maybe it's better to just ignore it, unless there is a reliable solution for that).
class GenericAlert {
public alert(info: any): any {
alert(info);
return true;
}
}
class NumberAlert extends GenericAlert {
// Can be entirely dropped after transform.
public alert(info: number): any {
return super.alert(info);
}
}
class StringAlert extends GenericAlert {
// CANNOT be dropped, because it returns void now.
public alert(info: string): void {
super.alert(info);
}
}
const genericLog = new GenericAlert();
genericLog.alert(123); // Nice
genericLog.alert('error'); // Nice
const numberLog = new NumberAlert();
numberLog.alert(123); // Nice
numberLog.alert('error'); // Bad (because it was narrowed)
const stringLog = new StringAlert();
stringLog.alert('error'); // Nice
stringLog.alert(123); // Bad (because it was narrowed)
this''d be really great to have!
Related:
- https://github.com/swc-project/swc/issues/7336
- https://github.com/swc-project/swc/issues/8177
- https://github.com/evanw/esbuild/issues/3463
- https://github.com/evanw/esbuild/issues/3464
- https://github.com/terser/terser/issues/1467
- https://github.com/terser/terser/issues/1468