Skip to content

Commit d124ec9

Browse files
committed
feat: update component type
1 parent 96f1100 commit d124ec9

File tree

4 files changed

+45
-25
lines changed

4 files changed

+45
-25
lines changed

.eslintrc.js

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,5 +20,14 @@ module.exports = {
2020
'@typescript-eslint/ban-ts-comment': 'off',
2121
'@typescript-eslint/explicit-module-boundary-types': 'off',
2222
'@typescript-eslint/no-empty-function': 'warn',
23+
'@typescript-eslint/ban-types': [
24+
'error',
25+
{
26+
extendDefaults: true,
27+
types: {
28+
'{}': false,
29+
},
30+
},
31+
],
2332
},
2433
}

example/main.tsx

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import '@abraham/reflection'
2-
import type { ClassType, ComponentProps } from '@/index'
2+
import type { ClassType, ComponentProps } from 'vue3-oop'
33
import { Autobind, Component, Computed, Hook, Link, Ref, VueComponent, VueService } from '@/index'
44
import { forwardRef, Inject, Injectable, SkipSelf } from 'injection-js'
55
import { createApp, VNodeChild, watch } from 'vue'
@@ -133,5 +133,19 @@ class Home extends VueComponent {
133133
}
134134
}
135135

136+
interface FooProps {
137+
value?: string
138+
'onUpdate:value'?: (value: string) => void
139+
slots: {
140+
item(): VNodeChild
141+
}
142+
}
143+
144+
class Foo extends VueComponent<FooProps> {
145+
render() {
146+
return undefined
147+
}
148+
}
149+
136150
const app = createApp(Home)
137151
app.mount('#app')

src/extends/component.ts

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { getCurrentInstance, provide, VNodeChild, VNodeProps } from 'vue'
1+
import { ComponentPublicInstance, getCurrentInstance, provide, VNodeChild, VNodeProps } from 'vue'
22
import { getEmitsFromProps, useCtx, useProps } from '../helper'
33
import { Hanlder, VueComponentStaticContructor, WithSlotTypes, WithVModel, WithVSlots } from '../type'
44
import { RefHandler } from '../decorators/ref'
@@ -8,9 +8,13 @@ import { LinkHandler } from '../decorators/link'
88

99
export const GlobalStoreKey = 'GlobalStoreKey'
1010

11-
type VueComponentProps<T extends Record<string, any>> = Omit<T, 'slots'> & WithVModel<T> & WithVSlots<T> & VNodeProps
11+
type VueComponentProps<T extends {}> = Omit<T, 'slots'> &
12+
WithVModel<T> &
13+
WithVSlots<T> &
14+
VNodeProps &
15+
Record<string, unknown>
1216

13-
export abstract class VueComponent<T = Record<string, any>> {
17+
export abstract class VueComponent<T extends {} = {}> {
1418
/** 装饰器处理 */
1519
static handler: Hanlder[] = [RefHandler, ComputedHandler, LinkHandler, HookHandler]
1620
/** 是否自定义解析组件 */
@@ -77,7 +81,5 @@ export abstract class VueComponent<T = Record<string, any>> {
7781
}
7882

7983
/** 渲染函数 */
80-
abstract render(): VNodeChild
81-
abstract render(ctx?: any): VNodeChild
82-
abstract render(ctx?: any, cache?: any[]): VNodeChild
84+
abstract render(ctx: ComponentPublicInstance, cache: any[]): VNodeChild
8385
}

src/type.ts

Lines changed: 13 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -28,40 +28,35 @@ export interface Hanlder {
2828
}
2929

3030
// 处理tsx slots 类型问题
31-
export type WithVSlots<T extends Record<string, any>> = 'slots' extends keyof T
32-
? {
33-
'v-slots'?: Partial<T['slots'] & { $stable: boolean; default(): VNodeChild }>
34-
[name: string]: any
35-
}
36-
: Record<string, any>
31+
export type WithVSlots<T extends {}> = {
32+
'v-slots'?: 'slots' extends keyof T
33+
? Partial<T['slots'] & { $stable: boolean; default(): VNodeChild }>
34+
: Partial<{ $stable: boolean; default(): VNodeChild }>
35+
}
3736

38-
export type WithSlotTypes<T extends Record<string, any>> = Omit<SetupContext, 'slots'> & {
39-
slots: Partial<T['slots'] & { default(): VNodeChild }>
37+
export type WithSlotTypes<T extends {}> = Omit<SetupContext, 'slots'> & {
38+
slots: 'slots' extends keyof T ? Partial<T['slots'] & { default(): VNodeChild }> : Partial<{ default(): VNodeChild }>
4039
}
4140

42-
type ModelProps<T extends Record<string, any>> = Exclude<
41+
type ModelProps<T extends {}> = Exclude<
4342
{
4443
[Prop in keyof T]: T extends { [k in Prop as `onUpdate:${k & string}`]?: any } ? Prop : never
4544
}[keyof T],
4645
undefined
4746
>
4847

49-
export type WithVModel<T extends Record<string, any>, U extends keyof T = ModelProps<T>> = {
48+
export type WithVModel<T extends {}, U extends keyof T = ModelProps<T>> = {
5049
[k in U as `v-model:${k & string}`]?: T[k] | [T[k], string[]]
5150
}
5251

53-
export type ComponentProps<T extends Record<string, any>> = ComponentPropsArray<T> | ComponentPropsObject<T>
52+
export type ComponentProps<T extends {}> = ComponentPropsArray<T> | ComponentPropsObject<T>
5453

55-
export type ComponentPropsObject<T extends Record<string, any>> = {
54+
export type ComponentPropsObject<T extends {}> = {
5655
[U in keyof Omit<T, 'slots'>]-?: Prop<any>
5756
}
58-
export type ComponentPropsArray<T extends Record<string, any>> = UnionToTuple<keyof Omit<T, 'slots'>>
57+
export type ComponentPropsArray<T extends {}> = UnionToTuple<keyof Omit<T, 'slots'>>
5958

60-
export type ComponentSlots<T extends { props: any }> = T extends { props: infer U }
61-
? 'v-slots' extends keyof U
62-
? U['v-slots']
63-
: Record<string, unknown>
64-
: never
59+
export type ComponentSlots<T extends { props: any }> = T['props']['v-slots']
6560

6661
/** 为了阻止ts把不相关的类也解析到metadata数据中,用这个工具类型包装一下类 */
6762
export type ClassType<T> = T

0 commit comments

Comments
 (0)