`override` modifier should able to be used with `declare` modifier
See original GitHub issueSuggestion
đ 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âŠ
Issue Analytics
- State:
- Created 10 months ago
- Comments:8
Top Related StackOverflow Question
Iâve put it in another way, hopefully it can convenience you more. https://github.com/microsoft/TypeScript/issues/51536
@fatcerberus Apologies If my words are too offensive. Iâm not very good at English after all. I just wanted to express my feeling on this issue and the direction it is developing. Now I believe you have acknowledged my frustration. I hope the user frustration still means something to TS devs. Maybe Iâll start a new issue and rephrase all about this after further discussion.
Itâs not about the new ES Class define behaviour, not on their part. This is exactly a TypeScript issue.
According to your own reply here, you are well aware of no matter what TS do, the eventual behaviour will change because of the underlying runtime. Then itâs ok to treat it transparently and not throw errors on this:
At least it should have an option to disable this error.
Property 'resident' will overwrite the base property in 'AnimalHouse'. If this is intentional, add an initializer. Otherwise, add a 'declare' modifier or remove the redundant declaration.(2612)FYI the decorator is working as expected. I authored those decorators. Itâs using the
metadata registeringapproach. Itâs not about the code not working; it works. Itâs about TypeScript not allowing this formerly-valid clear, precise way of writing code anymore, and proposes another much less favourable approach, known asdeclare.