-
Notifications
You must be signed in to change notification settings - Fork 25
Typescript 2.2 mixin conversion part 2 #110
Conversation
Codecov Report
@@ Coverage Diff @@
## master #110 +/- ##
==========================================
- Coverage 100% 99.78% -0.22%
==========================================
Files 17 16 -1
Lines 1393 1368 -25
Branches 253 251 -2
==========================================
- Hits 1393 1365 -28
- Misses 0 1 +1
- Partials 0 2 +2
Continue to review full report at Codecov.
|
} | ||
}; | ||
} | ||
export class DefaultObservableStore<T> extends |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this will get hit by the issue that incorrect code is emitted in the d.ts
, you'll need to declare the mixed type in a const
then use it in for extends
. Something like this:
export const DefaultObservableStoreBase = ObservableStoreMixin<T, CrudOptions, UpdateResults<T>, typeof StoreBase>(StoreBase)
export class DefaultObservableStore<T> extends DefaultObservableStoreBase<T, ObservableStoreMixinOptions> { }
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this is going to be problematic.
type Constructor<T> = new (...args: any[]) => T;
class GenericClass<T> {
}
interface GenericTrait<T> {
newGenericValue: T;
}
function MixinGeneric<T, C extends Constructor<GenericClass<T>>>(base: C): C & Constructor<GenericTrait<T>> {
return class extends base {
newGenericValue: T;
constructor(...args: any[]) {
super(...args);
}
};
}
class Child<T> extends GenericClass<T> {
child: T;
constructor(options: { childValue: string }) {
super();
}
}
// const ClassyMixinBase = MixinGeneric(Child);
// class ClassyMixin<T> extends ClassyMixinBase<T> {}
class ClassyMixin<T> extends MixinGeneric<T, typeof Child>(Child)<T> {}
// maintains signature
let classMixin: Child<string> & GenericTrait<string> = new ClassyMixin<string>({ childValue: 'string' });
// is a number
classMixin.child = 'abc';
// is not a number (is string)
classMixin.newGenericValue = 'abc';
This was the approach that we had to take to get the generic being mixed in to have the same type as the generic on the base class. If you comment out the existing class declaration and uncomment the workaround approach, this fails to compile, because the generic for the mixin defaults to {}
.
Passing any
as the first generic to MixinGeneric
fixes it, but then if classMixin
is not explicitly typed classMixin.newGenericValue
just becomes any
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This has now been updated to work around this by providing the Queryable store and the Observable store as classes instead of mixins.
9e78043
to
a814d00
Compare
a814d00
to
e4e9717
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
lots of code! but generally looks good. Could do with a follow up PR to add _
on private variables, clean up any formatting inconsistencies and check the visibility of class methods.
Type: feature
Description:
Converts the rest of the code base to use TypeScript 2.2 instead of dojo/compose
Related Issue: #108
Please review this checklist before submitting your PR: