Description
Suggestion
🔍 Search Terms
useDefineForClassFields
override declare
'override' modifier cannot be used with 'declare' modifier. ts(1243)
Property 'a' will overwrite the base property in 'Cls'. If this is intentional, add an initializer. Otherwise, add a 'declare' modifier or remove the redundant declaration.(2612)
✅ Viability Checklist
My suggestion meets these guidelines:
- This wouldn't be a breaking change in existing TypeScript/JavaScript code
- This wouldn't change the runtime behavior of existing JavaScript code
- This could be implemented without emitting different JS based on the types of the expressions
- This isn't a runtime feature (e.g. library functionality, non-ECMAScript syntax with JavaScript output, new syntax sugar for JS, etc.)
- This feature would agree with the rest of TypeScript's Design Goals.
⭐ Suggestion
When declaring class fields:
The override
modifier should be able to be used with declare
modifier.
Have !
work in the place of declare
OR:
Remove this error if !
or override
is specifically given: Property 'a' will overwrite the base property in 'Cls'. If this is intentional, add an initializer. Otherwise, add a 'declare' modifier or remove the redundant declaration.(2612)
📃 Motivating Example
Given a decorator Prop()
that somehow declares some metadata on the class field,
that would later be used in some other technical components like Database ORMs or Validators, etc.
Consider this example, before useDefineForClassFields
set to true
:
interface Animal {
animalStuff: any;
}
interface Dog extends Animal {
dogStuff: any;
}
class AnimalHouse {
internalProp: number;
@Prop({
default: {
animalStuff: 'food',
}
})
resident: Animal;
@Prop({
default: 'foo'
})
someOtherProp: string;
constructor(animal: Animal) {
this.resident = animal;
}
}
class DogHouse extends AnimalHouse {
@Prop({
default: {
animalStuff: 'food',
dogStuff: 'dog food',
}
})
override resident: Dog;
}
Note that the DogHouse
is defined quite straightforward and expected in a general sense.
Now after useDefineForClassFields
set to true
, the current way of specifying the DogHouse
becomes:
class DogHouse extends AnimalHouse {
@Prop({
default: {
animalStuff: 'food',
dogStuff: 'dog food',
}
})
declare resident: Dog;
}
It doesn't look too bad, but things can get more complicated:
class DogHouse extends AnimalHouse {
override internalProp: 42;
@Prop({
default: {
animalStuff: 'food',
dogStuff: 'dog food',
}
})
declare resident: Dog;
@Prop({
default: 'foo'
})
override someOtherProp: string = 'foo';
@Prop({
default: 'foo'
})
someOtherProp2: string;
}
Now it sucks.
The consistency and readability from using override
is completely screwed up by declare
.
At least the override
should be allowed to be used with declare
to make it suck a little less:
class DogHouse extends AnimalHouse {
override internalProp: 42;
@Prop({
default: {
animalStuff: 'food',
dogStuff: 'dog food',
}
})
declare override resident: Dog;
@Prop({
default: 'foo'
})
override someOtherProp: string = 'foo';
@Prop({
default: 'foo'
})
someOtherProp2: string;
}
The best case however, is to have !
work in the place of declare
:
class DogHouse extends AnimalHouse {
override internalProp: 42;
@Prop({
default: {
animalStuff: 'food',
dogStuff: 'dog food',
}
})
override resident!: Dog; // No declaration emit
@Prop({
default: 'bar'
})
override someOtherProp: string; // With declaration emit
@Prop({
default: 'foo'
})
someOtherProp2: string;
}
💻 Use Cases
As example suggested.
The code readability degradation from declare
is unacceptable.
I am using typescript with useDefineForClassFields
set to off
now.
Please consider my suggestion..