120 | );
121 | }
122 | });
123 | const w = mount(Comp);
124 | const inner = w.find(".inner");
125 | inner.trigger("keydown.up");
126 | inner.trigger("keydown.enter");
127 | inner.trigger("keydown.space");
128 | expect(spy.mock.calls).toEqual([["enter"]]);
129 | // all keydown events are not propagated
130 | expect(propagated).not.toHaveBeenCalled();
131 | });
132 | it("stop after", () => {
133 | const propagated = jest.fn();
134 | const Comp = Vue.extend({
135 | render(): VNode {
136 | return (
137 |
140 | );
141 | }
142 | });
143 | const w = mount(Comp);
144 | const inner = w.find(".inner");
145 | inner.trigger("keydown.up");
146 | inner.trigger("keydown.enter");
147 | inner.trigger("keydown.space");
148 | // keydown.enter is not propagated
149 | expect(propagated.mock.calls).toEqual([["up"], ["space"]]);
150 | });
151 | it("exact", () => {
152 | const spy = jest.fn();
153 | const Comp = Vue.extend({
154 | render(): VNode {
155 | return
spy(keyNames[e.keyCode]))} />;
156 | }
157 | });
158 | const w = mount(Comp);
159 | w.trigger("keydown.up", {
160 | ctrlKey: true
161 | });
162 | w.trigger("keydown.down", {
163 | altKey: true
164 | });
165 | w.trigger("keydown.left", {
166 | ctrlKey: true,
167 | altKey: true
168 | });
169 | w.trigger("keydown.right", {
170 | ctrlKey: true,
171 | shiftKey: true,
172 | altKey: true
173 | });
174 | expect(spy.mock.calls).toEqual([["left"]]);
175 | });
176 | });
177 |
--------------------------------------------------------------------------------
/test/jest/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "baseUrl": ".",
4 | "target": "es6",
5 | "module": "es2015",
6 | "moduleResolution": "node",
7 | "outDir": "./temp",
8 | "jsx": "preserve",
9 | "jsxFactory": "VueTsxSupport",
10 | "strict": true,
11 | "noUnusedParameters": true,
12 | "noImplicitReturns": true,
13 | "noFallthroughCasesInSwitch": true,
14 | "allowSyntheticDefaultImports": true,
15 | "inlineSourceMap": true,
16 | "paths": {
17 | "vue-tsx-support": ["../.."],
18 | "vue-tsx-support/*": ["../../*"],
19 | },
20 | "experimentalDecorators": true
21 | },
22 | "include": [
23 | "**/*.ts",
24 | "**/*.tsx",
25 | "../../enable-check.d.ts"
26 | ]
27 | }
28 |
--------------------------------------------------------------------------------
/test/tsc/allow-element-unknown-attrs/test.tsx:
--------------------------------------------------------------------------------
1 | import * as vuetsx from "vue-tsx-support";
2 | import Vue from "vue";
3 |
4 | const noop = () => {};
5 |
6 | /*
7 | * Intrinsic elements
8 | */
9 | function intrinsicElements() {
10 | // OK
11 |
;
12 | // OK: kebab-case attribute have not to be defined
13 |
;
14 | // OK: unknown element
15 |
;
16 |
17 | // OK: unknown attrs are allowed
18 |
;
19 | // @ts-expect-error
20 |
; //// TS2322 | TS2326: /Type '(0|number)' is not assignable to/
21 | // OK: unknown attrs are allowed
22 |
;
23 | // OK: unknown attrs are allowed
24 |
;
25 | }
26 |
27 | /*
28 | * Components written by standard way
29 | */
30 | function standardComponent() {
31 | const MyComponent = Vue.extend({
32 | props: ["a"],
33 | template: "
{{ a }}"
34 | });
35 |
36 | // Component unknown props are still rejected
37 |
38 | // NG: prop
39 | // @ts-expect-error: a does not exist
40 |
;
41 |
42 | // NG: HTML element
43 | // @ts-expect-error: accesskey does not exist
44 |
; //// TS2322 | TS2339 | TS2769: Property 'accesskey' does not exist
45 |
46 | // NG: native event handler
47 | // @ts-expect-error: nativeOnClick does not exist
48 |
;
49 | }
50 |
--------------------------------------------------------------------------------
/test/tsc/allow-element-unknown-attrs/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "../base",
3 | "include": [
4 | "*.tsx",
5 | "../../../enable-check.d.ts",
6 | "../../../options/allow-element-unknown-attrs.d.ts"
7 | ]
8 | }
9 |
--------------------------------------------------------------------------------
/test/tsc/allow-unknown-props/test.tsx:
--------------------------------------------------------------------------------
1 | import * as vuetsx from "vue-tsx-support";
2 | import Vue from "vue";
3 |
4 | const noop = () => {};
5 |
6 | /*
7 | * Intrinsic elements
8 | */
9 | function intrinsicElements() {
10 | // unknown attributes of intrinsic element are rejected
11 |
12 | // @ts-expect-error: domPropInnerHTML does not exist
13 |
;
14 | // @ts-expect-error: href does not exist
15 |
;
16 | }
17 |
18 | /*
19 | * Components written by standard way
20 | */
21 | function standardComponent() {
22 | const MyComponent = Vue.extend({
23 | props: ["a"],
24 | template: "
{{ a }}"
25 | });
26 |
27 | // OK
28 |
;
29 | // OK
30 |
;
31 | // OK
32 |
;
33 | }
34 |
35 | /*
36 | * ofType and convert
37 | */
38 | function convert() {
39 | const MyComponent = vuetsx.ofType<{ a: string }>().convert(Vue.extend({}));
40 |
41 | // OK
42 |
;
43 | // OK
44 |
;
45 | // OK
46 |
;
47 | // NG
48 | // @ts-expect-error: property 'a' is missing
49 |
;
50 | // NG
51 | // @ts-expect-error: property 'a' must be string
52 |
;
53 | }
54 |
--------------------------------------------------------------------------------
/test/tsc/allow-unknown-props/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "../base",
3 | "include": [
4 | "*.tsx",
5 | "../../../enable-check.d.ts",
6 | "../../../options/allow-unknown-props.d.ts"
7 | ]
8 | }
9 |
10 |
--------------------------------------------------------------------------------
/test/tsc/base.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "baseUrl": ".",
4 | "target": "es5",
5 | "jsx": "preserve",
6 | "jsxFactory": "VueTsxSupport",
7 | "module": "commonjs",
8 | "moduleResolution": "node",
9 | "incremental": true,
10 | "strict": true,
11 | "noImplicitReturns": true,
12 | "noFallthroughCasesInSwitch": true,
13 | "allowSyntheticDefaultImports": true,
14 | "experimentalDecorators": true,
15 | "paths": {
16 | "vue-tsx-support": ["../.."],
17 | "vue-tsx-support/*": ["../../*"]
18 | }
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/test/tsc/basic/builtin-components.tsx:
--------------------------------------------------------------------------------
1 |
;
2 |
3 |
;
4 |
5 |
done()} />;
6 |
7 | // @ts-expect-error: '(1|number)' is not assignable
8 | ;
9 |
10 | ;
11 |
12 | ;
13 |
14 | done()} />;
15 |
16 | // @ts-expect-error: '(1|number)' is not assignable
17 | ;
18 |
19 | ;
20 |
21 | ;
22 |
23 | ;
24 |
25 | ;
26 |
27 | // @ts-expect-error: 'number' is not assignable
28 | ;
29 |
--------------------------------------------------------------------------------
/test/tsc/basic/classComponent.tsx:
--------------------------------------------------------------------------------
1 | import Vue, { VNode } from "vue";
2 | import { Component, Prop } from "vue-property-decorator";
3 | import {
4 | InnerScopedSlots,
5 | DeclareOn,
6 | DeclareOnEvents,
7 | TsxTypeInfoOf,
8 | emit,
9 | emitOn,
10 | PickProps,
11 | DeclareProps,
12 | PickOwnProps,
13 | MakeOptional,
14 | AutoProps
15 | } from "vue-tsx-support";
16 |
17 | @Component
18 | class Test extends Vue {
19 | _tsx!: DeclareProps, "baz">> &
20 | DeclareOn<{ e1: string; e2: (p1: string, p2: number) => void }> &
21 | DeclareOnEvents<{ onE1: string; onE2: (p1: string, p2: number) => void }>;
22 |
23 | @Prop(String) foo!: string;
24 | @Prop(Number) bar?: number;
25 | @Prop({ type: String, default: "defaultValue" })
26 | baz!: string;
27 |
28 | bra!: number;
29 |
30 | $scopedSlots!: InnerScopedSlots<{
31 | default: { ssprops: string };
32 | optional?: string;
33 | }>;
34 |
35 | emitEvents() {
36 | emit(this, "e1", "value");
37 | // @ts-expect-error: '(number | 1)' is not assignable
38 | emit(this, "e1", 1);
39 |
40 | emit(this, "e2", "value", 1);
41 | // @ts-expect-error: Expected 4 arguments
42 | emit(this, "e2", "value");
43 | }
44 |
45 | emitOnEvents() {
46 | emitOn(this, "onE1", "value");
47 | // @ts-expect-error: Expected 4 arguments
48 | emitOn(this, "onE1", 1);
49 |
50 | emitOn(this, "onE2", "value", 1);
51 | // @ts-expect-error: Expected 4 arguments
52 | emitOn(this, "onE2", "value");
53 | }
54 | }
55 |
56 | class Test2 extends Test {
57 | piyo!: string[];
58 | _tsx!: TsxTypeInfoOf &
59 | DeclareProps> &
60 | DeclareOn<{ e3: () => void }>;
61 | $scopedSlots!: Test["$scopedSlots"] &
62 | InnerScopedSlots<{ additional: { foo: string; bar: number } }>;
63 |
64 | emitEvents2() {
65 | emit(this, "e1", "value");
66 | // @ts-expect-error: Expected 4 arguments
67 | emit(this, "e1", 1);
68 |
69 | emit(this, "e2", "value", 1);
70 | // @ts-expect-error: Expected 4 arguments
71 | emit(this, "e2", "value");
72 |
73 | emit(this, "e3");
74 | // @ts-expect-error: Expected 2 arguments
75 | emit(this, "e3", "value");
76 | }
77 | }
78 |
79 | // OK
80 | ;
81 | // OK
82 | ;
83 | // OK
84 | ;
85 | // OK
86 | ;
87 | // OK
88 | console.log(p.toLocaleLowerCase()),
92 | e2: (p1, p2) => console.log(p1.toLocaleLowerCase(), p2.toFixed())
93 | }}
94 | />;
95 | // @ts-expect-error: 'bra' does not exist
96 | ;
97 | // @ts-expect-error: 'foo' is missing
98 | ;
99 |
100 | console.log(p) }}
104 | />;
105 |
106 | // OK
107 | console.log(p)
111 | }}
112 | />;
113 |
114 | props.ssprops
118 | }}
119 | />;
120 |
121 | props.ssprops,
125 | optional: props => props.toUpperCase()
126 | }}
127 | />;
128 |
129 | props.toUpperCase()
134 | }}
135 | />;
136 |
137 | // OK
138 | ;
139 | // OK
140 | ;
141 | // OK
142 | console.log(p.toLocaleLowerCase()),
147 | e2: () => console.log("baz")
148 | }}
149 | />;
150 | // OK
151 | console.log(p.toLocaleLowerCase())]
156 | }}
157 | />;
158 |
159 | // @ts-expect-error: 'foo' is missing
160 | ; //// TS2322 | TS2326 | TS2769: 'foo' is missing
161 | // OK
162 | props.ssprops,
168 | additional: props => `${props.foo} ${props.bar}`
169 | }}
170 | />;
171 |
172 | @Component
173 | class GenericTest extends Vue {
174 | _tsx!: DeclareProps, "foo" | "bar">>;
175 |
176 | @Prop() foo!: T;
177 | @Prop(Function) bar!: (value: T) => string;
178 |
179 | $scopedSlots!: InnerScopedSlots<{
180 | default: { item: T };
181 | optional?: string;
182 | }>;
183 | }
184 |
185 | @Component
186 | class GenericParent extends Vue {
187 | value!: T;
188 | bar(value: T): string {
189 | return "";
190 | }
191 | render(): VNode {
192 | const GenericTestT = GenericTest as new () => GenericTest;
193 | return (
194 | {this.bar(props.item)}
199 | }}
200 | />
201 | );
202 | }
203 | }
204 |
205 | @Component
206 | class Test3 extends Vue {
207 | _tsx!: DeclareProps, "bra" | "test">>;
208 |
209 | @Prop(String) foo!: string;
210 | @Prop(Number) bar?: number;
211 |
212 | bra!: number;
213 |
214 | test() {}
215 | }
216 |
217 | // OK
218 | ;
219 | // OK
220 | ;
221 | // @ts-expect-error: 'foo' is missing
222 | ;
223 | // OK
224 | // @ts-expect-error: 'bra' does not exist
225 | ;
226 |
--------------------------------------------------------------------------------
/test/tsc/basic/componentFactory.tsx:
--------------------------------------------------------------------------------
1 | import Vue, { VNode } from "vue";
2 | import * as tsx from "vue-tsx-support";
3 |
4 | function standardComponent() {
5 | const MyComponent = tsx.component(
6 | {
7 | props: {
8 | foo: String,
9 | bar: Number,
10 | baz: String
11 | },
12 | render(): VNode {
13 | return {this.foo};
14 | }
15 | },
16 | /* requiredPropNames */ ["foo", "bar"]
17 | );
18 |
19 | /* OK */
20 | ;
21 | // baz is optional
22 | ;
23 | // other known attributes
24 | ;
25 |
26 | // @ts-expect-error
27 | ;
28 | // @ts-expect-error: 'bar' is missing
29 | ;
30 | ;
35 | ;
40 | ;
46 | ;
52 | }
53 |
54 | function standardComponentWithDataAndWatch() {
55 | const MyComponent = tsx.component({
56 | props: {
57 | foo: String
58 | },
59 | data() {
60 | return { a: "a" };
61 | },
62 | watch: {
63 | a(value: string) {
64 | console.log(value);
65 | }
66 | },
67 | render(): VNode {
68 | return {this.foo + this.a};
69 | }
70 | });
71 | }
72 |
73 | function functionalComponent() {
74 | const MyComponent = tsx.component(
75 | {
76 | functional: true,
77 | props: {
78 | foo: String,
79 | bar: Number,
80 | baz: String
81 | },
82 | render(_h, ctx): VNode {
83 | return {ctx.props.foo};
84 | }
85 | },
86 | ["foo", "bar"]
87 | );
88 | /* OK */
89 | ;
90 | // baz is optional
91 | ;
92 | // other known attributes
93 | ;
94 |
95 | /* NG */
96 | // @ts-expect-error
97 | ;
98 | // @ts-expect-error: 'bar' is missing
99 | ;
100 | // @ts-expect-error: '(0|number)' is not assignable
101 | ;
102 | // @ts-expect-error: '("bar"|string)' is not assignable'
103 | ;
104 | // @ts-expect-error: '(1|number)' is not assignable
105 | ;
106 | // @ts-expect-error: 'unknown' does not exist
107 | ;
108 | }
109 |
110 | function withoutRequiredPropNames() {
111 | const MyComponent = tsx.componentFactory.create({
112 | props: {
113 | foo: String,
114 | bar: Number,
115 | baz: String
116 | },
117 | render(): VNode {
118 | return {this.foo};
119 | }
120 | });
121 |
122 | /* OK */
123 | ;
124 | // foo, bar, baz are all optional
125 | ;
126 | // other known attributes
127 | ;
128 |
129 | // @ts-expect-error: '(0|number)' is not assignable
130 | ;
131 | // @ts-expect-error: '("bar"|string)' is not assignable
132 | ;
133 | // @ts-expect-error: '(1|number)' is not assignable
134 | ;
135 | // @ts-expect-error: 'unknown' does not exist
136 | ;
137 | }
138 |
139 | function inferRequiredPropNames() {
140 | const MyComponent = tsx.componentFactory.create({
141 | props: {
142 | foo: { type: String, required: true as true },
143 | bar: { type: Number, required: false },
144 | baz: String
145 | },
146 | render(): VNode {
147 | return {this.foo};
148 | }
149 | });
150 |
151 | /* OK */
152 | ;
153 | // foo is required, bar and baz are optional
154 | ;
155 | // other known attributes
156 | ;
157 |
158 | /* NG */
159 | // @ts-expect-error: 'foo' is missing
160 | ;
161 | ;
165 | ;
170 | ;
175 | ;
180 | }
181 |
182 | function withWrongRequiredPropNames() {
183 | // @ts-expect-error
184 | const MyComponent = tsx.component(
185 | {
186 | props: { foo: String }
187 | },
188 | ["foo", "unknown"]
189 | );
190 | }
191 |
192 | function componentFactoryOf() {
193 | const factory = tsx.componentFactoryOf<
194 | { onChange: number | string; onOk(target: any, id: string): void },
195 | { content: string }
196 | >();
197 | const MyComponent = factory.create({
198 | props: {
199 | foo: String,
200 | bar: Number
201 | },
202 | computed: {
203 | okNode(): VNode {
204 | return {this.$scopedSlots.content("foo")}
;
205 | },
206 | ngNode(): VNode {
207 | return (
208 |
209 | {
210 | // @ts-expect-error: ('0'|number) is not assignable
211 | this.$scopedSlots.content(0)
212 | }
213 |
214 | );
215 | }
216 | },
217 | render(): VNode {
218 | return {[this.okNode, this.ngNode]}
;
219 | }
220 | });
221 |
222 | /* checking type of scopedSlots */
223 | p }} />;
224 | p.toString() }}
227 | />;
228 | ;
232 |
233 | /* checking type of custom event handler */
234 | {}} />;
235 | {}} />;
236 | {}}
239 | />;
240 | {}}
243 | />;
244 | {
246 | console.log(id);
247 | }}
248 | />;
249 | }
250 |
251 | function optionalScopedSlot() {
252 | const factory = tsx.componentFactoryOf<{}, { required: string; optional?: number }>();
253 | const MyComponent = factory.create({
254 | props: {
255 | foo: String,
256 | bar: Number
257 | },
258 | render(): VNode {
259 | return (
260 |
261 | {this.$scopedSlots.optional!(1)}
262 | {
263 | // @ts-expect-error: possibly 'undefined'
264 | this.$scopedSlots.optional(1)
265 | }
266 |
267 | );
268 | }
269 | });
270 |
271 | /* checking type of scopedSlots */
272 | p.toUpperCase() }} />;
273 | p.toUpperCase(), optional: p => p.toString() }} />;
274 | p.toString() }}
277 | />;
278 | }
279 |
280 | function extendFrom() {
281 | /*
282 | * extend from tsx component
283 | */
284 | const Base1 = tsx.component(
285 | {
286 | props: { foo: String },
287 | computed: {
288 | fooUpper(): string {
289 | return this.foo.toUpperCase();
290 | }
291 | }
292 | },
293 | ["foo"]
294 | );
295 |
296 | const Ext1 = tsx.extendFrom(Base1).create({
297 | props: { bar: String },
298 | render(): VNode {
299 | return {this.fooUpper + this.bar}
;
300 | }
301 | });
302 |
303 | ;
304 | // @ts-expect-error: 'foo' is missing
305 | ;
306 | ;
312 |
313 | /*
314 | * extend from class base tsx component
315 | */
316 | class Base2 extends tsx.Component<{ foo: string }, { onOk: string }> {
317 | get fooUpper() {
318 | return this.$props.foo.toUpperCase();
319 | }
320 | }
321 |
322 | const Ext2 = tsx.extendFrom(Base2).create({
323 | props: { bar: String },
324 | render(): VNode {
325 | return {this.fooUpper + this.bar}
;
326 | }
327 | });
328 |
329 | ;
330 | // @ts-expect-error: 'foo' is missing
331 | ;
332 | ;
338 |
339 | /*
340 | * extend from standard component
341 | */
342 | const Base3 = Vue.extend({
343 | data() {
344 | return { foo: "fooValue" };
345 | }
346 | });
347 |
348 | const Ext3 = tsx.extendFrom(Base3).create({
349 | props: {
350 | bar: String
351 | },
352 | render(): VNode {
353 | return {this.foo + this.bar};
354 | }
355 | });
356 |
357 | ;
358 | ;
359 | ;
364 |
365 | /*
366 | * extend from standard class base component
367 | */
368 | class Base4 extends Vue {
369 | get foo() {
370 | return "fooValue";
371 | }
372 | }
373 |
374 | const Ext4 = tsx.extendFrom(Base4).create({
375 | props: {
376 | bar: String
377 | },
378 | render(): VNode {
379 | return {this.foo + this.bar};
380 | }
381 | });
382 |
383 | ;
384 | ;
385 | ;
390 | }
391 |
392 | function withXXX() {
393 | const Base = tsx
394 | .componentFactoryOf<{ onOk: { value: string } }, { default: { value: string } }>()
395 | .create({
396 | props: { foo: { type: String, required: true as true } }
397 | });
398 | const Ext = tsx.withNativeOn(Base);
399 | ;
400 | console.log(v.value)} />;
401 | v.value }} />;
402 | {}} />;
403 | // @ts-expect-error: 'foo' is missing
404 | ;
405 | }
406 |
407 | function emitHelper() {
408 | const Component = tsx.componentFactoryOf<{ onOk: string | number }>().create({
409 | props: { foo: { type: String, required: true } },
410 | methods: {
411 | emitOk() {
412 | tsx.emitOn(this, "onOk", "foo");
413 | tsx.emitOn(this, "onOk", 1);
414 | // @ts-expect-error
415 | tsx.emitOn(this, "onOk", true);
416 | // @ts-expect-error
417 | tsx.emitOn(this, "onNg", { value: "foo" });
418 | },
419 | updateFoo() {
420 | tsx.emitUpdate(this, "foo", "value");
421 | // @ts-expect-error
422 | tsx.emitUpdate(this, "fooo", "value");
423 | // @ts-expect-error
424 | tsx.emitUpdate(this, "foo", 0);
425 | }
426 | }
427 | });
428 | const Component2 = tsx.component({
429 | props: { foo: { type: String, required: true } },
430 | methods: {
431 | updateFoo() {
432 | tsx.emitUpdate(this, "foo", "value");
433 | // @ts-expect-error
434 | tsx.emitUpdate(this, "fooo", "value");
435 | // @ts-expect-error
436 | tsx.emitUpdate(this, "foo", 0);
437 | }
438 | }
439 | });
440 | }
441 |
--------------------------------------------------------------------------------
/test/tsc/basic/extend.tsx:
--------------------------------------------------------------------------------
1 | import Vue from "vue";
2 | import * as vuetsx from "vue-tsx-support";
3 |
4 | const noop = () => {};
5 |
6 | interface Props {
7 | foo: string;
8 | }
9 |
10 | interface Events {
11 | onOk: void;
12 | }
13 |
14 | interface Props2 {
15 | bar: string;
16 | }
17 |
18 | interface Events2 {
19 | onErr: string;
20 | }
21 |
22 | const a = { foo: 1, bar: "" };
23 |
24 | function by_createComponent() {
25 | const Base = vuetsx.createComponent({});
26 |
27 | // NG
28 | // @ts-expect-error: 'foo' is missing
29 | ;
30 | // OK
31 | ;
32 | // NG
33 | ;
38 | ;
43 |
44 | /* add more attributes */
45 | const Extend = vuetsx.ofType().extendFrom(Base);
46 | // OK
47 | console.log(s)} />;
48 | // @ts-expect-error: 'bar' is missing
49 | ;
50 | // @ts-expect-error: 'foo' is missing
51 | ;
52 |
53 | const WithNativeOn = vuetsx.withNativeOn(Base);
54 | ;
55 |
56 | const WithHtmlAttrs = vuetsx.withHtmlAttrs(Base);
57 | ;
58 |
59 | const WithUnknownProps = vuetsx.withUnknownProps(Base);
60 | ;
61 | }
62 |
63 | function by_convert() {
64 | const Base = vuetsx.ofType().convert(Vue.extend({}));
65 | const BaseWithStatic: typeof Base & { staticMember: number } = Base as any;
66 | BaseWithStatic.staticMember = 1;
67 |
68 | /* add more attributes */
69 | const Extend = vuetsx.ofType().extendFrom(BaseWithStatic);
70 | // OK
71 | console.log(s)} />;
72 | // OK
73 | console.log(Extend.staticMember);
74 | // @ts-expect-error: 'bar' is missing
75 | ; //// TS2322 | TS2326 | TS2769: 'bar' is missing
76 | // @ts-expect-error: 'foo' is missing
77 | ;
78 |
79 | const WithNativeOn = vuetsx.withNativeOn(Base);
80 | ;
81 |
82 | const WithHtmlAttrs = vuetsx.withHtmlAttrs(Base);
83 | ;
84 |
85 | const WithUnknownProps = vuetsx.withUnknownProps(Base);
86 | ;
87 | }
88 |
89 | function by_class() {
90 | class Base extends vuetsx.Component {
91 | someProp: string = "foo";
92 | someMethod() {}
93 | }
94 |
95 | /* add more attributes */
96 | const Extend = vuetsx.ofType().extendFrom(Base);
97 | // OK
98 | console.log(s)} />;
99 | // NG
100 | // @ts-expect-error: 'bar' is missing
101 | ;
102 | // NG
103 | // @ts-expect-error: 'foo' is missing
104 | ;
105 |
106 | // Extend inherits prototype of Base.
107 | const ext = new Extend();
108 | console.log(ext.someProp, ext.someMethod());
109 |
110 | const WithNativeOn = vuetsx.withNativeOn(Base);
111 | ;
112 | console.log(new WithNativeOn().someProp);
113 |
114 | const WithHtmlAttrs = vuetsx.withHtmlAttrs(Base);
115 | ;
116 | console.log(new WithHtmlAttrs().someProp);
117 |
118 | const WithUnknownProps = vuetsx.withUnknownProps(Base);
119 | ;
120 | console.log(new WithUnknownProps().someProp);
121 | }
122 |
123 | function by_componentFactory() {
124 | const Base = vuetsx.componentFactoryOf().create(
125 | {
126 | props: {
127 | foo: String
128 | },
129 | computed: {
130 | someProp(): string {
131 | return "";
132 | }
133 | },
134 | methods: {
135 | someMethod() {}
136 | }
137 | },
138 | ["foo"]
139 | );
140 |
141 | /* add more attributes */
142 | const Extend = vuetsx.ofType().extendFrom(Base);
143 | // OK
144 | console.log(s)} />;
145 | // NG
146 | // @ts-expect-error: 'bar' is missing
147 | ;
148 | // NG
149 | // @ts-expect-error: 'foo' is missing
150 | ;
151 |
152 | // Extend inherits prototype of Base.
153 | const ext = new Extend();
154 | console.log(ext.someProp, ext.someMethod());
155 |
156 | const WithNativeOn = vuetsx.withNativeOn(Base);
157 | ;
158 | console.log(new WithNativeOn().someProp);
159 |
160 | const WithHtmlAttrs = vuetsx.withHtmlAttrs(Base);
161 | ;
162 | console.log(new WithHtmlAttrs().someProp);
163 |
164 | const WithUnknownProps = vuetsx.withUnknownProps(Base);
165 | ;
166 | console.log(new WithUnknownProps().someProp);
167 | }
168 |
--------------------------------------------------------------------------------
/test/tsc/basic/mixin.tsx:
--------------------------------------------------------------------------------
1 | import Vue, { VNode } from "vue";
2 | import * as vuetsx from "vue-tsx-support";
3 |
4 | const noop = () => {};
5 |
6 | function basicFunctionary() {
7 | const factory = vuetsx.componentFactory
8 | .mixin({
9 | props: { foo: String },
10 | computed: {
11 | fooUpper(): string {
12 | return this.foo.toUpperCase();
13 | }
14 | }
15 | })
16 | .mixin(
17 | vuetsx.component(
18 | {
19 | props: { bar: String },
20 | computed: {
21 | barUpper(): string {
22 | return this.bar.toUpperCase();
23 | }
24 | }
25 | },
26 | ["bar"]
27 | )
28 | )
29 | .mixin(
30 | Vue.extend({
31 | data() {
32 | return { baz: "piyo" };
33 | }
34 | })
35 | );
36 |
37 | const Component = factory.create({
38 | props: { bra: Number },
39 | render(): VNode {
40 | return {this.fooUpper + this.barUpper + this.baz}
;
41 | }
42 | });
43 |
44 | ;
45 | // @ts-expect-error: 'bar' is missing
46 | ;
47 | }
48 |
--------------------------------------------------------------------------------
/test/tsc/basic/modifiers.tsx:
--------------------------------------------------------------------------------
1 | import Vue, { VNode } from "vue";
2 | import { modifiers as m } from "vue-tsx-support";
3 |
4 | function modifiers() {
5 | ;
6 | {})} />;
7 |
;
8 |
console.log(e.keyCode))} />;
9 |
console.log(e.keyCode))} />;
10 |
;
11 |
;
12 |
;
13 |
;
14 |
console.log(e.keyCode))} />;
15 |
;
16 |
console.log(e.keyCode))} />;
17 |
18 | // each modifiers can be specified only once
19 |
;
25 |
;
31 |
;
37 |
;
43 |
44 | // key modifier can be specified only once
45 |
;
51 |
;
56 |
;
62 |
63 | // mouse button modifier can be specified only once
64 |
;
70 |
;
76 |
77 | // key modifier and mouse button modifier can't be specified together
78 |
;
84 |
;
90 |
91 | // xxx and noxxx can't be specified together
92 |
;
98 |
;
104 |
;
110 |
;
116 |
;
122 |
;
128 |
;
134 |
;
140 | // 'exact' and other modkey can't be specified together
141 |
;
147 |
;
152 |
;
157 | }
158 |
--------------------------------------------------------------------------------
/test/tsc/basic/propsObject.tsx:
--------------------------------------------------------------------------------
1 | import Vue, { VNode } from "vue";
2 | import * as tsx from "vue-tsx-support";
3 |
4 | function standardComponent() {
5 | const MyComponent = tsx.component({
6 | props: {
7 | foo: { type: String, required: true as true },
8 | bar: Number
9 | },
10 | render(): VNode {
11 | return
{this.foo};
12 | }
13 | });
14 |
15 | /* OK */
16 |
;
17 | // bar is optional
18 |
;
19 | // @ts-expect-error: 'foo' is missing
20 |
;
21 |
22 | const MyComponent2 = tsx.withPropsObject(MyComponent);
23 | /* OK */
24 |
;
25 |
;
26 |
;
27 |
;
28 | // @ts-expect-error: 'foo' is missing
29 |
;
30 | }
31 |
--------------------------------------------------------------------------------
/test/tsc/basic/register-global-component.ts:
--------------------------------------------------------------------------------
1 | import * as vuetsx from "vue-tsx-support";
2 | import Vue from "vue";
3 |
4 | interface Props {
5 | text: string;
6 | }
7 |
8 | const MyComponent = vuetsx.createComponent
({});
9 | Vue.component("my-component", MyComponent);
10 |
--------------------------------------------------------------------------------
/test/tsc/basic/test.tsx:
--------------------------------------------------------------------------------
1 | import * as vuetsx from "vue-tsx-support";
2 | import component from "vue-class-component";
3 | import Vue from "vue";
4 |
5 | const noop = () => {};
6 |
7 | function assertType(value: T) {
8 | return value;
9 | }
10 |
11 | /*
12 | * Intrinsic elements
13 | */
14 | function intrinsicElements() {
15 | // OK
16 | ;
17 | // OK
18 | ;
19 | // OK
20 | ;
21 | // OK
22 | ;
23 | // OK
24 | ;
25 | // OK
26 | ;
27 | // OK
28 | ;
29 | // OK: kebab-case attribute have not to be defined
30 | ;
31 | // OK: unknown element
32 | ;
33 |
34 | // OK: specify style in 3 patterns
35 | ;
36 | ;
37 | ;
38 |
39 | // OK: inplace event handler: type of e.target is determined by containing tag.
40 | {
42 | assertType(e);
43 | assertType(e.target);
44 | }}
45 | />;
46 |
47 | const onInput = (e: InputEvent) => {};
48 | ;
49 |
50 | // @ts-expect-error
51 | ;
52 | // @ts-expect-error
53 | ;
54 | // @ts-expect-error
55 | ;
56 | }
57 |
58 | /*
59 | * Components written by standard way
60 | */
61 | function standardComponent() {
62 | const MyComponent = Vue.extend({
63 | props: ["a"],
64 | template: "{{ a }}"
65 | });
66 |
67 | // OK
68 | ;
69 | // OK
70 | ;
71 | // OK
72 | ;
73 | // OK
74 | ;
75 | // OK: unknown attributes are allowed in JSX spread.
76 | ;
77 |
78 | // @ts-expect-error
79 | ;
80 |
81 | // @ts-expect-error
82 | ;
83 |
84 | // NG: native event handler
85 | // @ts-expect-error
86 | ;
87 |
88 | // OK: specify style in 3 patterns
89 | ;
90 | ;
91 | ;
92 | }
93 |
94 | interface Props {
95 | a: string;
96 | b?: number;
97 | }
98 |
99 | interface Events {
100 | onChange: string;
101 | }
102 |
103 | interface ScopedSlots {
104 | default: { ssprops: string };
105 | }
106 |
107 | /*
108 | * ofType and convert
109 | */
110 | function convert() {
111 | const MyComponent1 = vuetsx.ofType().convert(
112 | Vue.extend({
113 | methods: { greet() {} }
114 | })
115 | );
116 | const MyComponent2 = vuetsx.ofType().convert(Vue.extend({}));
117 | const MyComponent3 = vuetsx.ofType().convert({} as any);
118 |
119 | // NG: `a` is required
120 | // @ts-expect-error: 'a' is missing
121 | ;
122 |
123 | let vm!: InstanceType;
124 | vm.greet(); // OK
125 |
126 | // OK
127 | ;
128 | // OK
129 | console.log(value.toUpperCase())} />;
130 | // NG: `c` is not defined
131 | ;
136 | // NG: `a` must be string
137 | ;
141 | // NG: `b` must be number
142 | ;
147 |
148 | // OK
149 | props.ssprops }} />;
150 | // NG
151 | ;
156 | // NG
157 |
161 | // @ts-expect-error: 'xxx' does not exist
162 | props.xxx
163 | }}
164 | />;
165 |
166 | // NG: `a` is required
167 | // @ts-expect-error
168 | ;
169 |
170 | // OK
171 | ;
172 | // OK
173 | console.log(value.toUpperCase())} />;
174 | // NG: `c` is not defined
175 | ;
180 | // NG: `a` must be string
181 | ;
185 | // NG: `b` must be number
186 | ;
191 |
192 | // NG: props object does not allow by default
193 | // @ts-expect-error
194 | ;
195 | }
196 |
197 | /*
198 | * createComponent
199 | */
200 | function createComponent() {
201 | const MyComponent = vuetsx.createComponent({});
202 |
203 | // NG: `a` is required
204 | // @ts-expect-error
205 | ;
206 | // OK
207 | ;
208 | // OK
209 | ;
210 | // NG: `c` is not defined
211 | ;
216 | // NG: `a` must be string
217 | ;
221 | // NG: `b` must be number
222 | ;
227 | }
228 |
229 | /*
230 | * vue-class-component
231 | */
232 | function vueClassComponent() {
233 | @component
234 | class MyComponent extends vuetsx.Component {}
235 |
236 | @component
237 | class MyComponent2 extends vuetsx.Component {
238 | render() {
239 | return {this.$scopedSlots.default({ ssprops: "foo" })}
;
240 | }
241 | }
242 |
243 | @component
244 | class MyComponent3 extends vuetsx.Component {
245 | render() {
246 | return (
247 |
248 | {this.$scopedSlots.default({
249 | // @ts-expect-error: 'number' is not assignable
250 | ssprops: 1
251 | })}
252 |
253 | );
254 | }
255 | }
256 |
257 | // NG: `a` is required
258 | // @ts-expect-error
259 | ;
260 |
261 | // OK
262 | ;
263 | // OK
264 | p.xxx }} />;
265 | // OK
266 | [{p.xxx}] }} />;
267 |
268 | // NG: `c` is not defined
269 | ;
274 | // NG: `a` must be string
275 | ;
279 | // NG: `b` must be number
280 | ;
285 |
286 | // OK
287 | p.ssprops }} />;
288 | // OK (unfortunately)
289 | ;
290 | // NG
291 |
295 | // @ts-expect-error: 'xxx' is not exist
296 | p.xxx
297 | }}
298 | />;
299 | }
300 |
301 | function knownAttrs() {
302 | const nope = () => {};
303 | const MyComponent = vuetsx.component({});
304 |
305 | ;
306 | ;
307 | ;
308 | }
309 |
310 | function functionalWrapper() {
311 | const MyComponent = vuetsx.component({});
312 | const Parent = vuetsx.component({
313 | functional: true,
314 | render(_h, { data, children }) {
315 | return {children};
316 | }
317 | });
318 | }
319 |
--------------------------------------------------------------------------------
/test/tsc/basic/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "../base",
3 | "include": [
4 | "*.ts",
5 | "*.tsx",
6 | "../../../enable-check.d.ts"
7 | ]
8 | }
9 |
--------------------------------------------------------------------------------
/test/tsc/basic/vca.tsx:
--------------------------------------------------------------------------------
1 | import { component, SetupContext, emit, emitOn, updateEmitter } from "vue-tsx-support/lib/vca";
2 | import { ref } from "@vue/composition-api";
3 | import { VNode } from "vue";
4 |
5 | const nope = () => undefined;
6 |
7 | const MyComponent = component({
8 | name: "MyComponentName",
9 | props: {
10 | foo: String,
11 | bar: { type: Boolean, required: true }
12 | },
13 | setup(props, ctx) {
14 | const el = ref(null);
15 |
16 | const emitUpdate = updateEmitter();
17 | emitUpdate(ctx, "foo", "value");
18 | // @ts-expect-error
19 | emitUpdate(ctx, "fooo", "value"); //// TS2345
20 | // @ts-expect-error
21 | emitUpdate(ctx, "foo", 0); //// TS2345
22 |
23 | return () => (
24 |
25 | {(ctx.slots.default || nope)()}
26 |
27 | );
28 | }
29 | });
30 |
31 | ; // OK
32 | ; // OK
33 | // @ts-expect-error
34 | ;
35 |
36 | const MyComponent2 = component({
37 | props: {
38 | foo: String
39 | },
40 | setup(
41 | props,
42 | ctx: SetupContext<
43 | { onCutstomEvent: string | number },
44 | { ss: string | boolean },
45 | { customEvent: string | number }
46 | >
47 | ) {
48 | const emitUpdate = updateEmitter();
49 | emit(ctx, "customEvent", "value");
50 | emitOn(ctx, "onCutstomEvent", "value");
51 | emit(ctx, "customEvent", 1);
52 | emitOn(ctx, "onCutstomEvent", 1);
53 |
54 | // @ts-expect-error
55 | emit(ctx, "customEvent2", "value"); //// TS2345
56 | // @ts-expect-error
57 | emitOn(ctx, "onCutstomEvent2", "value"); //// TS2345
58 |
59 | // @ts-expect-error
60 | emit(ctx, "customEvent", true); //// TS2345
61 | // @ts-expect-error
62 | emitOn(ctx, "onCutstomEvent", true); //// TS2345
63 |
64 | emitUpdate(ctx, "foo", "value");
65 | // @ts-expect-error
66 | emitUpdate(ctx, "fooo", "value"); //// TS2345
67 | // @ts-expect-error
68 | emitUpdate(ctx, "foo", 0); //// TS2345
69 |
70 | return () => (
71 |
72 | {ctx.slots.ss(true)}
73 | {ctx.slots.ss("value")}
74 |
75 | );
76 | }
77 | });
78 |
79 | const MyComponent3 = component({
80 | props: {
81 | foo: String
82 | },
83 | setup(props, ctx: SetupContext<{ onCutstomEvent: string | number }, { ss: string | boolean }>) {
84 | const emitUpdate = updateEmitter();
85 |
86 | emitOn(ctx, "onCutstomEvent", "value");
87 | emitOn(ctx, "onCutstomEvent", 1);
88 | // @ts-expect-error
89 | emitOn(ctx, "onCutstomEvent2", "value"); //// TS2345
90 | // @ts-expect-error
91 | emitOn(ctx, "onCutstomEvent", true); //// TS2345
92 |
93 | emitUpdate(ctx, "foo", "value");
94 | // @ts-expect-error
95 | emitUpdate(ctx, "fooo", "value"); //// TS2345
96 | // @ts-expect-error
97 | emitUpdate(ctx, "foo", 0); //// TS2345
98 |
99 | return () => ;
100 | }
101 | });
102 |
103 |
106 | console.log(
107 | // @ts-expect-error: 'toUpperCase' does not exist on type 'string | number'
108 | v.toUpperCase()
109 | )
110 | }
111 | />;
112 |
113 | const MyComponentWithRender = component({
114 | name: "MyComponentName",
115 | props: {
116 | foo: String,
117 | bar: { type: Boolean, required: true }
118 | },
119 | setup(props, ctx) {
120 | const el = ref(null);
121 | const greet = () => console.log("hello");
122 | const render_ = () => (
123 |
124 | {(ctx.slots.default || nope)()}
125 |
126 | );
127 | return {
128 | greet,
129 | render_
130 | };
131 | },
132 | render(): VNode {
133 | return this.render_();
134 | }
135 | });
136 |
137 | const vm = {} as InstanceType;
138 | vm.greet();
139 |
--------------------------------------------------------------------------------
/test/tsc/declaration/test.tsx:
--------------------------------------------------------------------------------
1 | import * as vuetsx from "vue-tsx-support";
2 | import Vue, { VNode, VNodeChildrenArrayContents, VNodeData, VueConstructor } from "vue";
3 |
4 | // export component with --declaration
5 |
6 | export const Component = vuetsx.component({
7 | name: "Component",
8 | props: {
9 | foo: String
10 | },
11 | render(h): VNode {
12 | return {this.foo}
;
13 | }
14 | });
15 |
16 | export const FunctionalComponent = vuetsx.component({
17 | functional: true,
18 | name: "Component2",
19 | props: {
20 | foo: String
21 | },
22 | render(h, { props }): VNode {
23 | return {props.foo}
;
24 | }
25 | });
26 |
27 | export class ClassComponent extends vuetsx.Component<
28 | { foo: string },
29 | { onClick: string },
30 | { default: string }
31 | > {}
32 |
--------------------------------------------------------------------------------
/test/tsc/declaration/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "../base",
3 | "compilerOptions": {
4 | "declaration": true
5 | },
6 | "include": [
7 | "*.tsx",
8 | "../../../enable-check.d.ts",
9 | "../../../options/allow-element-unknown-attrs.d.ts",
10 | "../../../options/allow-unknown-props.d.ts",
11 | "../../../options/enable-html-attrs.d.ts",
12 | "../../../options/enable-nativeon.d.ts",
13 | "../../../options/enable-vue-router.d.ts"
14 | ]
15 | }
16 |
17 |
--------------------------------------------------------------------------------
/test/tsc/enable-html-attrs/test.tsx:
--------------------------------------------------------------------------------
1 | import * as vuetsx from "vue-tsx-support";
2 | import Vue from "vue";
3 |
4 | const noop = () => {};
5 |
6 | /*
7 | * Components written by standard way
8 | */
9 | function standardComponent() {
10 | const MyComponent = Vue.extend({});
11 |
12 | // NG
13 | ;
17 | // OK
18 | ;
19 | // NG
20 | ;
24 | }
25 |
--------------------------------------------------------------------------------
/test/tsc/enable-html-attrs/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "../base",
3 | "include": [
4 | "*.tsx",
5 | "../../../enable-check.d.ts",
6 | "../../../options/enable-html-attrs.d.ts"
7 | ]
8 | }
9 |
--------------------------------------------------------------------------------
/test/tsc/enable-nativeon/test.tsx:
--------------------------------------------------------------------------------
1 | import * as vuetsx from "vue-tsx-support";
2 | import Vue from "vue";
3 |
4 | const noop = () => {};
5 | const func = (_: KeyboardEvent) => {};
6 |
7 | /*
8 | * Components written by standard way
9 | */
10 | function standardComponent() {
11 | const MyComponent = Vue.extend({});
12 |
13 | // NG
14 | ;
18 | // NG
19 | ;
23 | // OK
24 | ;
25 | // OK
26 | ;
27 | // NG
28 | ;
32 | // NG
33 | ;
39 | }
40 |
--------------------------------------------------------------------------------
/test/tsc/enable-nativeon/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "../base",
3 | "include": [
4 | "*.tsx",
5 | "../../../enable-check.d.ts",
6 | "../../../options/enable-nativeon.d.ts"
7 | ]
8 | }
9 |
--------------------------------------------------------------------------------
/test/tsc/enable-vuerouter/test.tsx:
--------------------------------------------------------------------------------
1 | import * as vuetsx from "vue-tsx-support";
2 | import Vue from "vue";
3 |
4 | const noop = () => {};
5 | const func = (_: KeyboardEvent) => {};
6 |
7 | /*
8 | * Components written by standard way
9 | */
10 | function standardComponent() {
11 | const MyComponent = Vue.extend({});
12 |
13 | ;
14 | ;
15 | // NG
16 | ;
22 | }
23 |
--------------------------------------------------------------------------------
/test/tsc/enable-vuerouter/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "../base",
3 | "include": [
4 | "*.tsx",
5 | "../../../enable-check.d.ts",
6 | "../../../options/enable-vue-router.d.ts"
7 | ]
8 | }
9 |
--------------------------------------------------------------------------------
/test/tsc/runner.js:
--------------------------------------------------------------------------------
1 | const path = require("path");
2 | const glob = require("glob");
3 | const { spawnSync } = require("child_process");
4 |
5 | const projects = glob.sync(path.join(__dirname, "**/tsconfig.json"));
6 |
7 | const runAll = () => {
8 | let hasError = false;
9 | for (const p of projects) {
10 | console.info(`testing ${p} ...`);
11 | const outDir = path.join(path.dirname(p), ".temp");
12 | const { status } = spawnSync("tsc", ["-p", p, "--outDir", outDir], {
13 | shell: true,
14 | stdio: "inherit"
15 | });
16 | if (status !== 0) {
17 | hasError = true;
18 | }
19 | }
20 | return hasError ? 1 : 0;
21 | };
22 |
23 | process.exit(runAll());
24 |
--------------------------------------------------------------------------------
/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target": "es5",
4 | "module": "es2015",
5 | "lib": [
6 | "dom",
7 | "es2015"
8 | ],
9 | "moduleResolution": "node",
10 | "declaration": true,
11 | "declarationDir": "./lib",
12 | "strict": true,
13 | "noUnusedParameters": true,
14 | "noImplicitReturns": true,
15 | "noFallthroughCasesInSwitch": true,
16 | "allowSyntheticDefaultImports": true,
17 | "inlineSourceMap": true,
18 | "esModuleInterop": true
19 | },
20 | "include": [
21 | "src/**/*.ts"
22 | ]
23 | }
24 |
--------------------------------------------------------------------------------
/types/base.d.ts:
--------------------------------------------------------------------------------
1 | import * as dom from "./dom";
2 | import Vue, {
3 | VNode,
4 | VNodeData,
5 | VNodeChildrenArrayContents,
6 | ComponentOptions,
7 | VueConstructor
8 | } from "vue";
9 | import { ScopedSlot } from "vue/types/vnode";
10 |
11 | export interface ElementAdditionalAttrs {
12 | // extension point.
13 | }
14 |
15 | export type ScopedSlotReturnType = ReturnType;
16 | export type TypedScopedSlot = (props: P) => ScopedSlotReturnType;
17 |
18 | export type KnownAttrs = {
19 | class?: VNodeData["class"];
20 | staticClass?: VNodeData["staticClass"];
21 | key?: VNodeData["key"];
22 | ref?: VNodeData["ref"] | { value: unknown };
23 | slot?: VNodeData["slot"];
24 | style?: VNodeData["style"] | string;
25 | domProps?: VNodeData["domProps"];
26 | attrs?: VNodeData["attrs"];
27 | hook?: VNodeData["hook"];
28 | on?: VNodeData["on"];
29 | nativeOn?: VNodeData["nativeOn"];
30 | id?: string;
31 | refInFor?: boolean;
32 | domPropsInnerHTML?: string;
33 | };
34 |
35 | export type Arg1 = T extends (arg1: infer A1) => any | undefined ? A1 : never;
36 |
37 | export type InnerScopedSlotReturnType = Vue["$scopedSlots"] extends {
38 | [name: string]: ((...args: any[]) => infer T) | undefined;
39 | }
40 | ? T
41 | : never;
42 | export type InnerScopedSlot = (props: T) => InnerScopedSlotReturnType;
43 | export type InnerScopedSlots = { [K in keyof T]: InnerScopedSlot> };
44 |
45 | export type ScopedSlotHandlers = {
46 | [K in keyof InnerSSType]: TypedScopedSlot>;
47 | };
48 |
49 | export type EventHandler = [E] extends [(...args: any[]) => any] ? E : (payload: E) => void;
50 | export type EventHandlers = { [K in keyof E]?: EventHandler | EventHandler[] };
51 |
52 | export type DeclareProps = { props: P };
53 | export type DeclareOnEvents = { onEvents: E };
54 | export type DeclareOn = { events: E };
55 | export type DeclareAttributes = { attributes: A };
56 |
57 | export type TsxComponentTypeInfo = DeclareProps &
58 | DeclareOnEvents &
59 | DeclareOn &
60 | DeclareAttributes;
61 |
62 | export type TsxTypeInfoOf = V extends { _tsx: infer T } ? T : {};
63 |
64 | export type PropsOf = TsxTypeInfoOf extends DeclareProps ? X : {};
65 | export type PrefixedEventsOf = TsxTypeInfoOf extends DeclareOnEvents