# Class definition order still sucks

**URL:** <https://es.discourse.group/t/class-definition-order-still-sucks/2154>\
**Category:** I have questions\
**Created:** [September 23, 2024, 7:22pm UTC](https://es.discourse.group/t/class-definition-order-still-sucks/2154 "2024-09-23T19:22:16Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![hydroperfox](https://yyz2.discourse-cdn.com/free1/user_avatar/es.discourse.group/hydroperfox/32/2233_2.png) [@hydroperfox](https://es.discourse.group/u/hydroperfox)\
**Post date:** [September 23, 2024, 7:22pm UTC](https://es.discourse.group/t/class-definition-order-still-sucks/2154/1 "2024-09-23T19:22:16Z")

</div>

I really don't like using React and I'd like to for example define components using class inheritance, but since in JavaScript 1.x classes are not verified partially (well, in ES4 (or JavaScript 2) they would be, so this topic wouldn't be an issue there), doing that doesn't always work depending on `import` paths:

```ts
// EventDispatcher.ts
import type { UIComponent } from "./UIComponent";
export class EventDispatcher
{
    // somewhere...
    dispatchEvent(evt:Event):boolean
    {
        // somewhere... read private fields
        // and do `o instanceof UIComponent`
        // getting a TypeScript error indicating that UIComponent
        // is a non-concrete "import type" type
    }
}

// UIComponent.ts
import { EventDispatcher } from "./EventDispatcher";
export class UIComponent extends EventDispatcher {}

// Button.ts
import { UIComponent } from "./UIComponent";
export class Button extends UIComponent {}

```

It doesn't always work because `EventDispatcher` may import `UIComponent.js` to perform checking of children, where a solution is IIRC doing `.constructor.name == "UIComponent"` instead of doing `instanceof UIComponent` or providing a `.isUIComponent()` method, which are all discomfortable.

I wonder when will this situation change...

To clarify, this is the common ECMAScript problem:

```javascript
class B extends A {}
class A {}

```

Error

---

<div class="post-metadata">

**Author:** ![hydroperfox](https://yyz2.discourse-cdn.com/free1/user_avatar/es.discourse.group/hydroperfox/32/2233_2.png) [@hydroperfox](https://es.discourse.group/u/hydroperfox)\
**Post date:** [September 23, 2024, 7:23pm UTC](https://es.discourse.group/t/class-definition-order-still-sucks/2154/2 "2024-09-23T19:23:14Z")

</div>

Oh, yeah, let's also not forget the sucking "Event" documentation too for people using `EventTarget` or `EventDispatcher`.

---

<div class="post-metadata">

**Author:** ![ljharb](https://yyz2.discourse-cdn.com/free1/user_avatar/es.discourse.group/ljharb/32/8_2.png) [@ljharb](https://es.discourse.group/u/ljharb)\
**Post date:** [September 23, 2024, 7:33pm UTC](https://es.discourse.group/t/class-definition-order-still-sucks/2154/3 "2024-09-23T19:33:37Z")

</div>

What do you mean by "verified partially"? (also there's no JS versions - ie, no 1.x or 2 JS, and ES4 was never actually a thing)

Certainly you shouldn't be relying on `.constructor` or `.name`, but `instanceof` should work fine for userland classes.

---

<div class="post-metadata">

**Author:** ![hydroperfox](https://yyz2.discourse-cdn.com/free1/user_avatar/es.discourse.group/hydroperfox/32/2233_2.png) [@hydroperfox](https://es.discourse.group/u/hydroperfox)\
**Post date:** [September 23, 2024, 7:48pm UTC](https://es.discourse.group/t/class-definition-order-still-sucks/2154/4 "2024-09-23T19:48:16Z")

</div>

By partially it'd be like passing through 3 phases: parsing, verification, and evaluation; there in verification classes are all defined partially in a first pass (that is, just nominally) and in eventual phases the classes are fully defined (including their members).

In actual ECMAScript, classes are defined immediately as they appear.

The thing with `instanceof` is that if `EventDispatcher.js` imports `UIComponent.js`, then there will be a cyclic import since `UIComponent.js` imports `EventDispatcher.js` too.

(Oh, but I think I did try using TypeScript's `import type`. Something happened and I don't recall what exactly.)

---

<div class="post-metadata">

**Author:** ![ljharb](https://yyz2.discourse-cdn.com/free1/user_avatar/es.discourse.group/ljharb/32/8_2.png) [@ljharb](https://es.discourse.group/u/ljharb)\
**Post date:** [September 23, 2024, 8:00pm UTC](https://es.discourse.group/t/class-definition-order-still-sucks/2154/5 "2024-09-23T20:00:40Z")

</div>

I'm also a bit confused, why would you want a parent to know anything about its children? That's not the way inheritance generally works.

---

<div class="post-metadata">

**Author:** ![hydroperfox](https://yyz2.discourse-cdn.com/free1/user_avatar/es.discourse.group/hydroperfox/32/2233_2.png) [@hydroperfox](https://es.discourse.group/u/hydroperfox)\
**Post date:** [September 23, 2024, 8:05pm UTC](https://es.discourse.group/t/class-definition-order-still-sucks/2154/6 "2024-09-23T20:05:06Z")

</div>

It happens that the `dispatchEvent()` method isn't meant to be overriden by `UIComponent` but implemented into `EventDispatcher` itself so that it can traverse children (which `EventDispatcher` doesn't define by itself) for reading `EventDispatcher` private fields.

---

<div class="post-metadata">

**Author:** ![hydroperfox](https://yyz2.discourse-cdn.com/free1/user_avatar/es.discourse.group/hydroperfox/32/2233_2.png) [@hydroperfox](https://es.discourse.group/u/hydroperfox)\
**Post date:** [September 23, 2024, 8:06pm UTC](https://es.discourse.group/t/class-definition-order-still-sucks/2154/7 "2024-09-23T20:06:55Z")

</div>

Ah, right: about `import type` the issue is that `instanceof` can't use an `import type` "type" in TypeScript.

I have updated the original message.
