Evan You 7 лет назад
Родитель
Сommit
3a7d11ca15
2 измененных файлов с 50 добавлено и 7 удалено
  1. 4 3
      packages/core/src/componentUtils.ts
  2. 46 4
      packages/core/src/optional/mixin.ts

+ 4 - 3
packages/core/src/componentUtils.ts

@@ -62,9 +62,7 @@ export function initializeComponentInstance(instance: ComponentInstance) {
     )
   }
 
-  instance.$options =
-    instance.constructor.options ||
-    resolveComponentOptions(instance.constructor)
+  instance.$options = resolveComponentOptions(instance.constructor)
   instance.$parentVNode = currentVNode as MountedVNode
 
   // renderProxy
@@ -262,6 +260,9 @@ export function createComponentClassFromOptions(
 export function resolveComponentOptions(
   Component: ComponentClass
 ): ComponentOptions {
+  if (Component.options) {
+    return Component.options
+  }
   const descriptors = Object.getOwnPropertyDescriptors(Component)
   const options = {} as any
   for (const key in descriptors) {

+ 46 - 4
packages/core/src/optional/mixin.ts

@@ -1,6 +1,48 @@
-import { ComponentInstance } from '../component'
-import { ComponentOptions } from '../componentOptions'
+import { Component } from '../component'
 
-export interface Mixin extends ComponentOptions {}
+interface ComponentConstructor<This = Component> {
+  new (): This
+}
 
-export function applyMixins(Component: ComponentInstance, mixins: Mixin[]) {}
+// mind = blown
+type UnionToIntersection<U> = (U extends any
+  ? (k: U) => void
+  : never) extends ((k: infer I) => void)
+  ? I
+  : never
+
+type ExtractInstance<T> = T extends (infer U)[]
+  ? UnionToIntersection<U extends ComponentConstructor<infer V> ? V : never>
+  : never
+
+function mixins<T extends ComponentConstructor[], V = ExtractInstance<T>>(
+  ...args: T
+): ComponentConstructor<V>
+function mixins(...args: any[]): any {
+  // TODO
+}
+
+/* Example usage
+
+class Foo extends Component<{ foo: number }> {
+  test() {
+
+  }
+}
+
+class Bar extends Component<{ bar: string }> {
+  ok() {
+
+  }
+}
+
+class Baz extends mixins(Foo, Bar) {
+  created() {
+    this.foo
+    this.bar
+    this.test()
+    this.ok()
+  }
+}
+
+*/