|
1 | 1 | import { expectError, expectType } from './index' |
2 | 2 | import { |
| 3 | + ComponentOptions, |
3 | 4 | DefineComponent, |
4 | 5 | defineComponent, |
5 | | - FunctionalComponent |
| 6 | + FunctionalComponent, |
| 7 | + getCurrentInstance, |
| 8 | + h, |
| 9 | + ref, |
| 10 | + SetupContext, |
| 11 | + Prop, |
| 12 | + VNodeChild |
6 | 13 | } from 'vue' |
7 | 14 | import { Options, Vue } from 'vue-class-component' |
8 | 15 | import { mount } from '../src' |
@@ -179,7 +186,7 @@ declare const FunctionalComponentEmit: FunctionalComponent< |
179 | 186 | level: number |
180 | 187 | }, |
181 | 188 | { hello: (foo: string, bar: string) => void } |
182 | | -> |
| 189 | + > |
183 | 190 |
|
184 | 191 | mount(FunctionalComponent) |
185 | 192 | mount(defineComponent(FunctionalComponent)) |
@@ -211,6 +218,78 @@ class ClassComponent extends Vue { |
211 | 218 | expectError(mount(ClassComponent, {}).vm.changeMessage()) |
212 | 219 | mount(ClassComponent, {}).vm.changeMessage('') |
213 | 220 |
|
| 221 | +// region custom class component implement |
| 222 | +class CustomClassComponent<Props extends {} = {}> { |
| 223 | + static defaultProps?: Record<string, Prop<any>> | string[] |
| 224 | + private static __vccValue?: ComponentOptions |
| 225 | + static get __vccOpts(): ComponentOptions { |
| 226 | + if (this.__vccValue) return this.__vccValue |
| 227 | + const CompConstructor = this |
| 228 | + return (this.__vccValue = { |
| 229 | + name: CompConstructor.name, |
| 230 | + props: CompConstructor.defaultProps, |
| 231 | + setup(props, ctx) { |
| 232 | + const instance = new CompConstructor() |
| 233 | + return instance.render.bind(instance) |
| 234 | + } |
| 235 | + }) |
| 236 | + } |
| 237 | + constructor() { |
| 238 | + const instance = getCurrentInstance()! |
| 239 | + this.props = instance.props as Props |
| 240 | + // @ts-expect-error no explicit setupContext on instance |
| 241 | + this.context = instance.setupContext as SetupContext |
| 242 | + } |
| 243 | + |
| 244 | + props: Props |
| 245 | + get $props() { |
| 246 | + return this.props |
| 247 | + } |
| 248 | + context: SetupContext |
| 249 | + render(): VNodeChild {} |
| 250 | +} |
| 251 | +class NoPropCustomClassComponent extends CustomClassComponent { |
| 252 | + count = ref(0) |
| 253 | + changeCount(count: number) { |
| 254 | + this.count.value = count |
| 255 | + } |
| 256 | + render() { |
| 257 | + return h('div', `hello world ${this.count.value}`) |
| 258 | + } |
| 259 | +} |
| 260 | + |
| 261 | +// @ts-expect-error changeCount expects an argument |
| 262 | +expectError(mount(NoPropCustomClassComponent, {}).vm.changeCount()) |
| 263 | +mount(NoPropCustomClassComponent, {}).vm.changeCount(2) |
| 264 | + |
| 265 | +interface CustomClassComponentProps { |
| 266 | + size: 'small' | 'large' |
| 267 | + age?: number |
| 268 | +} |
| 269 | + |
| 270 | +class WithPropCustomClassComponent extends CustomClassComponent<CustomClassComponentProps> { |
| 271 | + static defaultProps: (keyof CustomClassComponentProps)[] = ['size', 'age'] |
| 272 | + count = ref(0) |
| 273 | + changeCount(count: number) { |
| 274 | + this.count.value = count |
| 275 | + } |
| 276 | + render() { |
| 277 | + return h('div', `hello world ${this.count.value}${this.props.size}`) |
| 278 | + } |
| 279 | +} |
| 280 | + |
| 281 | +expectError( |
| 282 | + // @ts-expect-error should has props error |
| 283 | + mount<WithPropCustomClassComponent, CustomClassComponentProps>(WithPropCustomClassComponent, { |
| 284 | + props: {} |
| 285 | + }) |
| 286 | +) |
| 287 | +mount<WithPropCustomClassComponent, CustomClassComponentProps>(WithPropCustomClassComponent, { |
| 288 | + props: { size: 'small' } |
| 289 | +}) |
| 290 | + |
| 291 | +// endregion |
| 292 | + |
214 | 293 | // default props |
215 | 294 | const Foo = defineComponent({ |
216 | 295 | props: { |
|
0 commit comments