Allow class to extend from generic type parameters (#4890)
Motivation: want to support mixin-like patterns
type Constructor = new (...args: any[]) => T;
class Base {
constructor(public x: number, public y: number) {}
}
class Derived extends Base {
constructor(x: number, y: number, public z: number) {
super(x, y);
}
}
function Tagged<T extends Constructor<Base>>(superClass: T) {
return class extends superClass {
_tag: string;
constructor(...args: any[]) {
super(...args);
this._tag = "hello";
this.x
}
}
}
-
Problems: substitutability is not guaranteed between the new type and a type parameter.
- Something that is not necessary to address now.
-
Right now this is modeled with intersections.
- When you intersect two types, TypeScript just recursively intersects members.
- Problem: but right now signatures of intersection types are just sequentially concatenated togehter.
- Example: the result of
T & U & V has signatures of T followed by those of U followed by those of V.
- Idea: what if whenever we see a
(...args) => XXX signature, take other signatures and intersect the return type.
- Example
T has a signature (x, y, z) => Derived
C has type: (...args: any[]) => C
T & C has type (x, y, z) => C & Derived
- Question: What if
...args: string[]?
- Question: Does order matter?
- A: Yes;
(...args: any[]) => XXX only changes things if it's the latter type in the intersection.
- Question: Can the latter type have multiple overloads in the type for this to take effect?
- Question: Should these types by swapped around?
- Discussion
- Probably less code uses
(...args: any[]) => XXX as first overload.
- Methods and constructor in derived class should have overloads that come first - more accurately models signatures.
- A: Yes, they should.
-
Issues: what about generic constructors?
- Can't model that well, but our thoughts are that we can eventually iterate.
-
Can we allow code that derives from any?
- Conversation slips into call-site inference discussion.
Override keyword (#13217)
Current rules:
override is only allowed on class property declarations.
--noImplicitOverride method.
- Errors if you override a method without
override.
- Includes augmentations.
- Should you be able to
override static members?
- What about
override abstract methods?
- Why?
- You want to substitute the signature, but acknowledge the
override.
- If so, why can't an interface have this?
- Let's say no for now.
- Resolution: let's take a look at the PR.
Expando object support
let x = {};
// add stuff to `x`
Another pattern:
Mainly for existing JavaScript patterns.
- Problem: "gazillion" different ways of achieving this.
Out of time.
Allow class to extend from generic type parameters (#4890)
Motivation: want to support mixin-like patterns
Problems: substitutability is not guaranteed between the new type and a type parameter.
Right now this is modeled with intersections.
T & U & Vhas signatures ofTfollowed by those ofUfollowed by those ofV.(...args) => XXXsignature, take other signatures and intersect the return type.Thas a signature(x, y, z) => DerivedChas type:(...args: any[]) => CT & Chas type (x, y, z) => C & Derived...args: string[]?any[](...args: any[]) => XXXonly changes things if it's the latter type in the intersection.(...args: any[]) => XXXas first overload.Issues: what about generic constructors?
Can we allow code that derives from
any?Override keyword (#13217)
Current rules:
overrideis only allowed on class property declarations.--noImplicitOverridemethod.override.overridestaticmembers?override abstractmethods?override.Expando object support
Another pattern:
Mainly for existing JavaScript patterns.
Out of time.