question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Support expression in extends clauses

See original GitHub issue

Demo

Classes can extend arbitrary expressions, but Closure is throwing a warning on an unknown type.

const Mixin = (superclass) => class extends superclass {
  // ...
}

Note, the warning from the compiler service at least doesn’t have a line number:

JSC_TYPE_PARSE_ERROR: Bad type annotation. Unknown type superclass at line -1 beyond character 1

Issue Analytics

  • State:closed
  • Created 7 years ago
  • Comments:22 (8 by maintainers)

github_iconTop GitHub Comments

2reactions
ChadKillingsworthcommented, Oct 26, 2016
1reaction
justinfagnanicommented, Oct 26, 2016

Yes, it just creates prototype chains.

I think this expansion is assuming a lot about the mixin function - that it only returns a class expression and does no other computation. In practice we have some utilities that will modify a mixin function so that it does things like de-duplicate multiple applications on a prototype chain (not reapply if it has already been applied), or cache and reuse the result of an application to a prototype chain. See DeDupe and Cache here: https://github.com/justinfagnani/mixwith.js

So I think it’d be better to type the mixin function itself somehow. To say that it takes a constructor of type S and returns a constructor of type M extends S

Please my abuse of the type annotations below, and in general the level of crazy, but this is close to what I would want to type check mixins:

import {Mixin} from '../mixwith/mixwith.js';

/**
 * @template {HTMLElement} S
 * @param {function(new:S)} superclass
 * @return {M extends S}
 */
const AwesomeElement =  Mixin((superclass) => /** @typedef M */ class M extends superclass {
});

class MyElement extends AwesomeElement(HTMLElement) {
}

A few things that I knowingly fudge:

  1. How do I specify that a template extends a type? @template {HTMLElement} S is my attempt to do Java’s <S extends HTMLElement>.
  2. function(new:S) is my attempt to specify a first-class type, the metaclass of S
  3. M extends S is a type operator that represents the type created by class M extends S{}
  4. class M extends superclass: M doesn’t exist in the outer scope, so it needs some way to be pushed up. /** @typedef M */ is that 😕
  5. I’m assuming that at the callsite for AwesomeElement(HTMLElement) the typechecker can calculate the result type and validate that AwesomeElement can extend HTMLElement (overrides are compatible).
Read more comments on GitHub >

github_iconTop Results From Across the Web

Extending class 'extends' to work with expressions #239
In the extends position, e.g. "class A extends B", the extends clause must be an expression, or a Generic NamedTypeReference.
Read more >
Scheme - Expressions
Semantics: A cond expression is evaluated by evaluating the <test> expressions of successive <clause>s in order until one of them evaluates to a...
Read more >
Extending EF Core 'where' clause with custom expression
MVC Core EF does not yet support SPs so I create a partial class with the same name as the model. Here is...
Read more >
Documentation - TypeScript 1.6
The extends clause of a class previously required a type reference to be specified. It now accepts an expression optionally followed by a...
Read more >
Assignment 3: Primitives, Conditionals, and Dispatch
The goal of this assignment is to extend the parser, interpreter, and compiler with some simple unary numeric and boolean operations and two ......
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found