Don't require to implement optional abstract properties
Nadie ha tomado este issue todavía.
Evaluación
- Dificultad
- 5/5
- Tiempo estimado
- Más de una semana
- Aptitud para principiantes
- 35/100
- Tipo de issue
- Nueva funcionalidad
- Claridad
- Bastante claro
- Estado de actividad
- Estancado
- Stack tecnológico
- typescript
- Área
- compilers
Línea de trabajo
Comienza reproduciendo los ejemplos enlazados de TypeScript Playground y compara el comportamiento actual de las propiedades abstractas opcionales y no opcionales. Revisa las issues relacionadas 6413 y 22939 para conocer el contexto del diseño. Se considera terminado cuando las propiedades abstractas opcionales puedan omitirse en las subclases y se sigan admitiendo las formas de implementación descritas en la issue, sin modificar el comportamiento existente de las propiedades obligatorias.
Escrito por el modelo de indexación a partir del texto del issue.
Descripción
Search Terms
abstract optional override
Suggestion
If in abstract class abstract property is marked as optional, allow child classes not to implement it.
So I suggest to remove an error for property x of class D in the following code:
abstract class A {
protected abstract readonly x?: number
protected abstract readonly y: number | undefined
public doSmth() {
console.log(this.x, this.y)
}
}
class D extends A {
protected readonly y = 10
}
new D().doSmth()
But property y still must be implemented.
Note that we already can do some sort of it
interface I {
propertyCanSkip?: number
propertyMustImplement: number | undefined
methodCanSkip?(): void
methodMustImplement(): void
}
abstract class A {
propertyCanSkip?: number
abstract propertyMustImplement: number | undefined
abstract propertyMustImplementToo?: number
methodCanSkip?(): void
abstract methodMustImplement(): void
abstract methodMustImplementToo?(): void
}
class CA extends A {
/*
Non-abstract class 'CA' does not implement inherited abstract member 'methodMustImplement' from class 'A'.(2515)
Non-abstract class 'CA' does not implement inherited abstract member 'methodMustImplementToo' from class 'A'.(2515)
Non-abstract class 'CA' does not implement inherited abstract member 'propertyMustImplement' from class 'A'.(2515)
Non-abstract class 'CA' does not implement inherited abstract member 'propertyMustImplementToo' from class 'A'.(2515)
*/
}
class CI implements I {
/*
Class 'CI' incorrectly implements interface 'I'.
Type 'CI' is missing the following properties from type 'I': propertyMustImplement, methodMustImplement(2420)
*/
}
But there is a set of problems for properties
We have two ways to override property (via property declaration or via getter and setter). And now (in TS4) the limitation have changed. For nonabstract property base class always defines how it should be implemented in children.
Let's look what implementations are possible (don't forget about useDefineForClassFields compiler flag that makes it more important):
| Code | Property can be omitted | Child can implement as property | Child can implement as get/set |
|---|---|---|---|
propertyCanSkip?: number |
Yes | Yes | No |
abstract propertyMustImplement: number | undefined |
No | Yes | Yes (except https://github.com/microsoft/TypeScript/issues/40632) |
abstract propertyMustImplementToo?: number |
No | Yes | Yes (except https://github.com/microsoft/TypeScript/issues/40632) |
get getter?(): number |
N/A | N/A | N/A |
abstract get getterMustImplement(): number | undefined |
No | No | Yes |
abstract getterToo?(): number |
N/A | N/A | N/A |
It's easy to see, that if the property should really be optional, there is only one way to make it such which will not allow to implement it as getter and setter. But we have 2 absolutely identical lines with optional and nonoptional abstract property. I see no sense for them to be synonyms as ? in the 3rd line definitely says that the property is optional, but doesn't give me ability to make so in further code.
So I propose to change this table in following way:
| Code | Property can be omitted | Child can implement as property | Child can implement as get/set |
|---|---|---|---|
propertyCanSkip?: number |
Yes | Yes | No |
abstract propertyMustImplement: number | undefined |
No | Yes | Yes |
abstract propertyCanSkipToo?: number |
Yes | Yes | Yes |
get getter?(): number |
N/A | N/A | N/A |
abstract get getterMustImplement(): number | undefined |
No | No | Yes |
abstract get getterCanSkipToo?(): number |
Yes | No | Yes |
Abstract getter is NOT a part of this feature request, just shown for consistency.
Use Cases
Provide ability to list and use for reading an optional property in abstract class without limiting a way of its implementation in child classes. Such problem occured in a real project because of migration from TS3 to TS4. Before that it was possible, but because of breaking changes of TS4 it's not anymore.
abstract class A {
protected readonly smth?: number
public f() {
console.log(this.smth)
}
}
class B extends A {
smth = 10
}
class C extends A {
get smth() { return Math.random() }
}
class D extends A {
}
new B().f()
new C().f()
new D().f()
Examples
See above.
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, etc.)
- This feature would agree with the rest of TypeScript's Design Goals.
Why it's not a breaking change?
It changes behavior of existing construction, but it's not a breaking change in terms of code.
If you had your code working and you have
abstract propertyMustImplementToo?: number
in it, that means that you implemented this property in all child classes. So after its meaning changes all you code keeps being valid and compiles into absolutely the same javascript code as before. Nothing changed.
At the same time, for further development you have to decide whether you want to allow child classes to skip the property or not. If yes, or you don't care - keep it with ? as it is. If no then update it to
abstract propertyMustImplementToo: number | undefined
without any other changes needed.
Related Issues:
https://github.com/microsoft/TypeScript/issues/6413
https://github.com/microsoft/TypeScript/issues/22939
- Lenguaje dominante
- Go
- Estrellas
- 111k
- Forks
- 14.4k
- Merge medio
- 1 d 19 h
- PR fusionados (30 d)
- 117
Guía de contribución
Primeros pasos
- Lee el issue completo y luego la guía de contribución del proyecto.
- Comenta en el issue que vas a ocuparte — evita que dos personas hagan lo mismo.
- Haz un fork del repositorio y trabaja en una rama.
- Abre un pull request que haga referencia al número del issue.
Más de microsoft/TypeScript
-
Dificultad 2/5 1-3 horas Aptitud para principiantes 88/100
microsoft/TypeScript#64322 · 2 comentarios · 1 reacción · 2 asignados ·
-
Possible Improvement
Dificultad 2/5 1-3 horas Aptitud para principiantes 78/100
microsoft/TypeScript#64278 · 1 comentario · 1 reacción ·
-
Docs
Dificultad 2/5 1-3 horas Aptitud para principiantes 70/100
microsoft/TypeScript#64118 · 1 comentario ·
-
Dificultad 1/5 Menos de una hora Aptitud para principiantes 88/100
microsoft/TypeScript#64094 ·
-
Docs
Dificultad 2/5 1-3 horas Aptitud para principiantes 76/100
microsoft/TypeScript#63959 · 5 comentarios ·
Todos los issues de microsoft/TypeScript
Issues similares
-
optimization optimization:agents-md-curator
Dificultad 2/5 1-3 horas Aptitud para principiantes 86/100
githubnext/gh-aw-cao#13143 ·
-
Dificultad 2/5 1-3 horas Aptitud para principiantes 84/100
blinklabs-io/bursa#904 ·
-
Dificultad 2/5 1-3 horas Aptitud para principiantes 84/100
yanet-platform/ipfw-go#129 ·
-
bug confmap/provider/googlesecretmanagerprovider needs triage
Dificultad 2/5 1-3 horas Aptitud para principiantes 72/100
open-telemetry/opentelemetry-collector-contrib#51273 · 2 comentarios ·
-
bug: AI Gateway client filter lists "Unknown" twice when NULL and literal Unknown clients coexist Abiertobug
Dificultad 2/5 1-3 horas Aptitud para principiantes 90/100