|
| 1 | +import { EmitFn, EmitsOptions } from '../componentEmits' |
| 2 | +import { |
| 3 | + ComponentObjectPropsOptions, |
| 4 | + ExtractPropTypes |
| 5 | +} from '../componentProps' |
1 | 6 | import { Slots } from '../componentSlots'
|
| 7 | +import { Directive } from '../directives' |
2 | 8 | import { warn } from '../warning'
|
3 | 9 |
|
4 | 10 | interface DefaultContext {
|
5 |
| - props: Record<string, unknown> |
| 11 | + props: {} |
6 | 12 | attrs: Record<string, unknown>
|
7 | 13 | emit: (...args: any[]) => void
|
8 | 14 | slots: Slots
|
9 | 15 | }
|
10 | 16 |
|
| 17 | +interface InferredContext<P, E> { |
| 18 | + props: Readonly<P> |
| 19 | + attrs: Record<string, unknown> |
| 20 | + emit: EmitFn<E> |
| 21 | + slots: Slots |
| 22 | +} |
| 23 | + |
| 24 | +type InferContext<T extends Partial<DefaultContext>, P, E> = { |
| 25 | + [K in keyof DefaultContext]: T[K] extends {} ? T[K] : InferredContext<P, E>[K] |
| 26 | +} |
| 27 | + |
| 28 | +/** |
| 29 | + * This is a subset of full options that are still useful in the context of |
| 30 | + * <script setup>. Technically, other options can be used too, but are |
| 31 | + * discouraged - if using TypeScript, we nudge users away from doing so by |
| 32 | + * disallowing them in types. |
| 33 | + */ |
| 34 | +interface Options<E extends EmitsOptions, EE extends string> { |
| 35 | + emits?: E | EE[] |
| 36 | + name?: string |
| 37 | + inhertiAttrs?: boolean |
| 38 | + directives?: Record<string, Directive> |
| 39 | +} |
| 40 | + |
11 | 41 | /**
|
12 | 42 | * Compile-time-only helper used for declaring options and retrieving props
|
13 |
| - * and the setup context inside <script setup>. |
| 43 | + * and the setup context inside `<script setup>`. |
14 | 44 | * This is stripped away in the compiled code and should never be actually
|
15 | 45 | * called at runtime.
|
16 | 46 | */
|
17 |
| -export function useOptions<T extends Partial<DefaultContext> = {}>( |
18 |
| - opts?: any // TODO infer |
19 |
| -): { [K in keyof DefaultContext]: T[K] extends {} ? T[K] : DefaultContext[K] } { |
| 47 | +// overload 1: no props |
| 48 | +export function useOptions< |
| 49 | + T extends Partial<DefaultContext> = {}, |
| 50 | + E extends EmitsOptions = EmitsOptions, |
| 51 | + EE extends string = string |
| 52 | +>( |
| 53 | + options?: Options<E, EE> & { |
| 54 | + props?: undefined |
| 55 | + } |
| 56 | +): InferContext<T, {}, E> |
| 57 | + |
| 58 | +// overload 2: object props |
| 59 | +export function useOptions< |
| 60 | + T extends Partial<DefaultContext> = {}, |
| 61 | + E extends EmitsOptions = EmitsOptions, |
| 62 | + EE extends string = string, |
| 63 | + PP extends string = string, |
| 64 | + P = Readonly<{ [key in PP]?: any }> |
| 65 | +>( |
| 66 | + options?: Options<E, EE> & { |
| 67 | + props?: PP[] |
| 68 | + } |
| 69 | +): InferContext<T, P, E> |
| 70 | + |
| 71 | +// overload 3: object props |
| 72 | +export function useOptions< |
| 73 | + T extends Partial<DefaultContext> = {}, |
| 74 | + E extends EmitsOptions = EmitsOptions, |
| 75 | + EE extends string = string, |
| 76 | + PP extends ComponentObjectPropsOptions = ComponentObjectPropsOptions, |
| 77 | + P = ExtractPropTypes<PP> |
| 78 | +>( |
| 79 | + options?: Options<E, EE> & { |
| 80 | + props?: PP |
| 81 | + } |
| 82 | +): InferContext<T, P, E> |
| 83 | + |
| 84 | +// implementation |
| 85 | +export function useOptions() { |
20 | 86 | if (__DEV__) {
|
21 | 87 | warn(
|
22 | 88 | `defineContext() is a compiler-hint helper that is only usable inside ` +
|
23 | 89 | `<script setup> of a single file component. It will be compiled away ` +
|
24 | 90 | `and should not be used in final distributed code.`
|
25 | 91 | )
|
26 | 92 | }
|
27 |
| - return null as any |
| 93 | + return 0 as any |
28 | 94 | }
|
0 commit comments