Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

185
Vistas
Strange behaivour of TypeScript when extending class with similar namespace structure

Recently I've been trying to create a type library for library written in JS. When I declared all namespaces, classes and interfaces, some classes started to give me an error TS2417. I checked if there was any problem with invalid overriding of methods or properties, but I couldn't find anything. After some time I've found that the problematic class had same name as one of the namespaces (for example class A.B and namespace A.B). But this didn't cause any trouble. The problem was that the parent class (of the problematic class) had, just as the problematic class, namespace which was named exactly the same and this namespace and the namespace of the problematic class had class, which was named exactly the same, but had different interface (it is very hard for me to describe the problem, so I simulated here).

So the question is, what causes this problem?

In this example the problematic class is A.C, but it has problems due to incompatible constructors of classes A.C.X and A.B.X.

declare namespace A {
  class B {

  }

  namespace B {
    class X {

    }
  }

  class C extends A.B {

  }

  namespace C {
    class X {
      constructor(x: number)
    }
  }
}
about 4 years ago · Juan Pablo Isaza
1 Respuestas
Responde la pregunta

0

(In the following I will dispense with the namespace A)

With the exception of the construct signature, the static side of a class is checked for substitutability the same way that the instance side is; so if you have class X { static prop: string = "" }, then you can't have class Y extends X { static prop: number = 2}. When you say class Y extends X you are declaring that, among other things, Y.prop is assignable to X.prop. See microsoft/TypeScript#4628 for more information. Not everyone likes this constraint, but it's there.


That means the following should work with no error:

const X: typeof B.X = C.X; // should be okay
new X(); // should be okay

But a concrete implementation of your classes could easily lead to a runtime error:

class B {
  static X = class { }
}

class C extends B {
  static X = class {
    constructor(x: number) {
      x.toFixed();
    }
  }
}

Here, C.X is a class constructor which requires a number input. But B.X is a class constructor which does not require any input at all. And if you treat the former as if it were the latter, than at runtime you will be calling the toFixed() method on undefined. Oops.

And that's why class C extends B generates a compiler error; to protect you against substitutability issues arising from the static side of a class.

Playground link to code

about 4 years ago · Juan Pablo Isaza Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda