Skip to content
This repository was archived by the owner on Dec 25, 2024. It is now read-only.

Commit e35f027

Browse files
committed
feat: global types
1 parent 7a01448 commit e35f027

File tree

7 files changed

+192
-4
lines changed

7 files changed

+192
-4
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,8 +74,8 @@ const Vue2SFC = transform(`
7474
- [x] Merge with normal scripts
7575
- [x] Vite plugin
7676
- [x] Webpack plugin
77+
- [x] Global types
7778
- [ ] Top-level await
78-
- [ ] Global types
7979

8080
## Sponsors
8181

global.d.ts

Lines changed: 181 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,181 @@
1+
import {
2+
ComponentPropsOptions,
3+
ExtractPropTypes,
4+
} from '@vue/composition-api'
5+
6+
export type ObjectEmitsOptions = Record<
7+
string,
8+
((...args: any[]) => any) | null
9+
>
10+
11+
export type EmitsOptions = ObjectEmitsOptions | string[]
12+
13+
export type EmitsToProps<T extends EmitsOptions> = T extends string[]
14+
? {
15+
[K in string & `on${Capitalize<T[number]>}`]?: (...args: any[]) => any
16+
}
17+
: T extends ObjectEmitsOptions
18+
? {
19+
[K in string &
20+
`on${Capitalize<string & keyof T>}`]?: K extends `on${infer C}`
21+
? T[Uncapitalize<C>] extends null
22+
? (...args: any[]) => any
23+
: (
24+
...args: T[Uncapitalize<C>] extends (...args: infer P) => any
25+
? P
26+
: never
27+
) => any
28+
: never
29+
}
30+
: {}
31+
32+
export type UnionToIntersection<U> = (
33+
U extends any ? (k: U) => void : never
34+
) extends (k: infer I) => void
35+
? I
36+
: never
37+
38+
export type EmitFn<
39+
Options = ObjectEmitsOptions,
40+
Event extends keyof Options = keyof Options
41+
> = Options extends Array<infer V>
42+
? (event: V, ...args: any[]) => void
43+
: {} extends Options // if the emit is empty object (usually the default value for emit) should be converted to function
44+
? (event: string, ...args: any[]) => void
45+
: UnionToIntersection<
46+
{
47+
[key in Event]: Options[key] extends (...args: infer Args) => any
48+
? (event: key, ...args: Args) => void
49+
: (event: key, ...args: any[]) => void
50+
}[Event]
51+
>
52+
53+
declare global {
54+
/**
55+
* Vue `<script setup>` compiler macro for declaring component props. The
56+
* expected argument is the same as the component `props` option.
57+
*
58+
* Example runtime declaration:
59+
* ```js
60+
* // using Array syntax
61+
* const props = defineProps(['foo', 'bar'])
62+
* // using Object syntax
63+
* const props = defineProps({
64+
* foo: String,
65+
* bar: {
66+
* type: Number,
67+
* required: true
68+
* }
69+
* })
70+
* ```
71+
*
72+
* Equivalent type-based decalration:
73+
* ```ts
74+
* // will be compiled into equivalent runtime declarations
75+
* const props = defineProps<{
76+
* foo?: string
77+
* bar: number
78+
* }>()
79+
* ```
80+
*
81+
* This is only usable inside `<script setup>`, is compiled away in the
82+
* output and should **not** be actually called at runtime.
83+
*/
84+
// overload 1: runtime props w/ array
85+
export function defineProps<PropNames extends string = string>(
86+
props: PropNames[]
87+
): Readonly<{ [key in PropNames]?: any }>
88+
// overload 2: runtime props w/ object
89+
export function defineProps<
90+
PP extends ComponentPropsOptions = ComponentPropsOptions
91+
>(props: PP): Readonly<ExtractPropTypes<PP>>
92+
// overload 3: typed-based declaration
93+
export function defineProps<TypeProps>(): Readonly<TypeProps>
94+
95+
/**
96+
* Vue `<script setup>` compiler macro for declaring a component's emitted
97+
* events. The expected argument is the same as the component `emits` option.
98+
*
99+
* Example runtime declaration:
100+
* ```js
101+
* const emit = defineEmits(['change', 'update'])
102+
* ```
103+
*
104+
* Example type-based decalration:
105+
* ```ts
106+
* const emit = defineEmits<{
107+
* (event: 'change'): void
108+
* (event: 'update', id: number): void
109+
* }>()
110+
*
111+
* emit('change')
112+
* emit('update', 1)
113+
* ```
114+
*
115+
* This is only usable inside `<script setup>`, is compiled away in the
116+
* output and should **not** be actually called at runtime.
117+
*/
118+
// overload 1: runtime emits w/ array
119+
export function defineEmits<EE extends string = string>(
120+
emitOptions: EE[]
121+
): EmitFn<EE[]>
122+
export function defineEmits<E extends EmitsOptions = EmitsOptions>(
123+
emitOptions: E
124+
): EmitFn<E>
125+
export function defineEmits<TypeEmit>(): TypeEmit
126+
127+
/**
128+
* Vue `<script setup>` compiler macro for declaring a component's exposed
129+
* instance properties when it is accessed by a parent component via template
130+
* refs.
131+
*
132+
* `<script setup>` components are closed by default - i.e. varaibles inside
133+
* the `<script setup>` scope is not exposed to parent unless explicitly exposed
134+
* via `defineExpose`.
135+
*
136+
* This is only usable inside `<script setup>`, is compiled away in the
137+
* output and should **not** be actually called at runtime.
138+
*/
139+
export function defineExpose(exposed?: Record<string, any>): void
140+
141+
type NotUndefined<T> = T extends undefined ? never : T
142+
143+
type InferDefaults<T> = {
144+
[K in keyof T]?: NotUndefined<T[K]> extends
145+
| number
146+
| string
147+
| boolean
148+
| symbol
149+
| Function
150+
? NotUndefined<T[K]>
151+
: (props: T) => NotUndefined<T[K]>
152+
}
153+
154+
type PropsWithDefaults<Base, Defaults> = Base &
155+
{
156+
[K in keyof Defaults]: K extends keyof Base ? NotUndefined<Base[K]> : never
157+
}
158+
159+
/**
160+
* Vue `<script setup>` compiler macro for providing props default values when
161+
* using type-based `defineProps` decalration.
162+
*
163+
* Example usage:
164+
* ```ts
165+
* withDefaults(defineProps<{
166+
* size?: number
167+
* labels?: string[]
168+
* }>(), {
169+
* size: 3,
170+
* labels: () => ['default label']
171+
* })
172+
* ```
173+
*
174+
* This is only usable inside `<script setup>`, is compiled away in the output
175+
* and should **not** be actually called at runtime.
176+
*/
177+
export function withDefaults<Props, Defaults extends InferDefaults<Props>>(
178+
props: Props,
179+
defaults: Defaults,
180+
): PropsWithDefaults<Props, Defaults>
181+
}

index.d.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
import './global'
2+
export * from './dist/index'

package.json

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
"description": "",
55
"main": "dist/index.js",
66
"module": "dist/index.mjs",
7-
"types": "dist/index.d.ts",
7+
"types": "index.d.ts",
88
"exports": {
99
".": {
1010
"require": "./dist/index.js",
@@ -32,7 +32,8 @@
3232
},
3333
"keywords": [],
3434
"files": [
35-
"dist"
35+
"dist",
36+
"*.d.ts"
3637
],
3738
"scripts": {
3839
"prepublishOnly": "nr build",

playground/HelloWorld.vue

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
import { ref, computed, watch } from '@vue/composition-api'
1414
1515
const props = withDefaults(defineProps<{ msg: string; name: string | number }>(), { msg: 'Hello' })
16-
const emit = defineEmits()
16+
const emit = defineEmits(['update'])
1717
1818
const count = ref(0)
1919
const doubled = computed(() => count.value * 2)

vite-plugin.d.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
import './global'
2+
export * from './dist/vite-plugin'

webpack-plugin.d.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
import './global'
2+
export * from './dist/webpack-plugin'

0 commit comments

Comments
 (0)