Skip to content

Commit beab2a0

Browse files
committed
fix(types): infer types through sync$
1 parent b4b72b8 commit beab2a0

File tree

8 files changed

+46
-118
lines changed

8 files changed

+46
-118
lines changed

packages/docs/src/components/docsearch/doc-search.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ export const DocSearch = component$((props: DocSearchProps) => {
7777
<div
7878
class={{ docsearch: true, 'ai-result-open': aiResultOpen.value }}
7979
window:onKeyDown$={[
80-
sync$((event: KeyboardEvent) => {
80+
sync$((event) => {
8181
if (event.key === 'k' && (event.metaKey || event.ctrlKey)) {
8282
event.preventDefault();
8383
}

packages/docs/src/routes/api/qwik/api.json

Lines changed: 4 additions & 4 deletions
Large diffs are not rendered by default.

packages/docs/src/routes/api/qwik/index.mdx

Lines changed: 8 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -2805,7 +2805,7 @@ export type QRL<TYPE = unknown> = {
28052805
getCaptured(): unknown[] | null;
28062806
getSymbol(): string;
28072807
getHash(): string;
2808-
dev: QRLDev | null;
2808+
dev?: QRLDev | null;
28092809
} & BivariantQrlFn<QrlArgs<TYPE>, QrlReturn<TYPE>>;
28102810
```
28112811
@@ -2913,7 +2913,7 @@ export type QRL<TYPE = unknown> = {
29132913
getCaptured(): unknown[] | null;
29142914
getSymbol(): string;
29152915
getHash(): string;
2916-
dev: QRLDev | null;
2916+
dev?: QRLDev | null;
29172917
} & BivariantQrlFn<QrlArgs<TYPE>, QrlReturn<TYPE>>;
29182918
```
29192919
@@ -8747,68 +8747,14 @@ Function to extract.
87478747
## SyncQRL
87488748
87498749
```typescript
8750-
export interface SyncQRL<TYPE extends Function> extends QRL<TYPE>
8750+
export type SyncQRL<TYPE extends Function> = QRL<TYPE> & {
8751+
__brand__SyncQRL__: TYPE;
8752+
resolved: TYPE;
8753+
dev?: QRLDev | null;
8754+
} & BivariantQrlFn<QrlArgs<TYPE>, QrlReturn<TYPE>>;
87518755
```
87528756
8753-
**Extends:** [QRL](#qrl)&lt;TYPE&gt;
8754-
8755-
<table><thead><tr><th>
8756-
8757-
Property
8758-
8759-
</th><th>
8760-
8761-
Modifiers
8762-
8763-
</th><th>
8764-
8765-
Type
8766-
8767-
</th><th>
8768-
8769-
Description
8770-
8771-
</th></tr></thead>
8772-
<tbody><tr><td>
8773-
8774-
[\_\_brand\_\_SyncQRL\_\_](#)
8775-
8776-
</td><td>
8777-
8778-
</td><td>
8779-
8780-
TYPE
8781-
8782-
</td><td>
8783-
8784-
</td></tr>
8785-
<tr><td>
8786-
8787-
[dev](#)
8788-
8789-
</td><td>
8790-
8791-
</td><td>
8792-
8793-
QRLDev \| null
8794-
8795-
</td><td>
8796-
8797-
</td></tr>
8798-
<tr><td>
8799-
8800-
[resolved](#)
8801-
8802-
</td><td>
8803-
8804-
</td><td>
8805-
8806-
TYPE
8807-
8808-
</td><td>
8809-
8810-
</td></tr>
8811-
</tbody></table>
8757+
**References:** [QRL](#qrl)
88128758
88138759
[Edit this section](https://github.com/QwikDev/qwik/tree/main/packages/qwik/src/core/shared/qrl/qrl.public.ts)
88148760

packages/docs/src/routes/demo/cookbook/drag&drop/basic/index.tsx

Lines changed: 16 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -19,14 +19,14 @@ export default component$(() => {
1919
class="h-[25em] w-80 rounded-xl border-2 border-dashed border-gray-300 bg-white p-6 shadow-xs transition-all duration-300 hover:border-gray-400 [&[data-over]]:border-blue-300 [&[data-over]]:bg-blue-50"
2020
preventdefault:dragover
2121
preventdefault:drop
22-
onDragOver$={sync$((_: DragEvent, currentTarget: HTMLDivElement) => {
22+
onDragOver$={sync$((_, currentTarget) => {
2323
currentTarget.setAttribute('data-over', 'true');
2424
})}
25-
onDragLeave$={sync$((_: DragEvent, currentTarget: HTMLDivElement) => {
25+
onDragLeave$={sync$((_, currentTarget) => {
2626
currentTarget.removeAttribute('data-over');
2727
})}
2828
onDrop$={[
29-
sync$((e: DragEvent, currentTarget: HTMLDivElement) => {
29+
sync$((e, currentTarget) => {
3030
const id = e.dataTransfer?.getData('text');
3131
currentTarget.dataset.droppedId = id;
3232
currentTarget.removeAttribute('data-over');
@@ -51,14 +51,12 @@ export default component$(() => {
5151
data-id={item.id}
5252
class="min-h-[62px] mb-3 cursor-move select-none rounded-lg border border-gray-200 bg-white p-4 transition-all duration-200 hover:-translate-y-1 hover:shadow-md active:scale-95"
5353
draggable
54-
onDragStart$={sync$(
55-
(e: DragEvent, currentTarget: HTMLDivElement) => {
56-
const itemId = currentTarget.getAttribute('data-id');
57-
if (e.dataTransfer && itemId) {
58-
e.dataTransfer?.setData('text/plain', itemId);
59-
}
54+
onDragStart$={sync$((e, currentTarget) => {
55+
const itemId = currentTarget.getAttribute('data-id');
56+
if (e.dataTransfer && itemId) {
57+
e.dataTransfer?.setData('text/plain', itemId);
6058
}
61-
)}
59+
})}
6260
>
6361
<span class="text-lg text-gray-700">{item.content}</span>
6462
</div>
@@ -69,14 +67,14 @@ export default component$(() => {
6967
class="h-[25em] w-80 rounded-xl border-2 border-dashed border-gray-300 bg-white p-6 shadow-xs transition-all duration-300 hover:border-gray-400 [&[data-over]]:border-blue-300 [&[data-over]]:bg-blue-50"
7068
preventdefault:dragover
7169
preventdefault:drop
72-
onDragOver$={sync$((_: DragEvent, currentTarget: HTMLDivElement) => {
70+
onDragOver$={sync$((_, currentTarget) => {
7371
currentTarget.setAttribute('data-over', 'true');
7472
})}
75-
onDragLeave$={sync$((_: DragEvent, currentTarget: HTMLDivElement) => {
73+
onDragLeave$={sync$((_, currentTarget) => {
7674
currentTarget.removeAttribute('data-over');
7775
})}
7876
onDrop$={[
79-
sync$((e: DragEvent, currentTarget: HTMLDivElement) => {
77+
sync$((e, currentTarget) => {
8078
const id = e.dataTransfer?.getData('text');
8179
currentTarget.dataset.droppedId = id;
8280
currentTarget.removeAttribute('data-over');
@@ -101,14 +99,12 @@ export default component$(() => {
10199
data-id={item.id}
102100
class="min-h-[62px] mb-3 cursor-move select-none rounded-lg border border-gray-200 bg-white p-4 transition-all duration-200 hover:-translate-y-1 hover:shadow-md active:scale-95"
103101
draggable
104-
onDragStart$={sync$(
105-
(e: DragEvent, currentTarget: HTMLDivElement) => {
106-
const itemId = currentTarget.getAttribute('data-id');
107-
if (e.dataTransfer && itemId) {
108-
e.dataTransfer?.setData('text/plain', itemId);
109-
}
102+
onDragStart$={sync$((e, currentTarget) => {
103+
const itemId = currentTarget.getAttribute('data-id');
104+
if (e.dataTransfer && itemId) {
105+
e.dataTransfer?.setData('text/plain', itemId);
110106
}
111-
)}
107+
})}
112108
>
113109
<span class="text-lg text-gray-700">{item.content}</span>
114110
</div>

packages/docs/src/routes/docs/cookbook/sync-events/index.mdx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ A typical way to deal with these limitations is to split the event handling into
1919
1. `sync$()` which is called synchronously and can call methods such as `event.preventDefault()` and `event.stopPropagation()`.
2020
2. `$()` which is called asynchronously and can close over the state and call other functions, and has no restriction on the size.
2121

22-
Because `sync$()` can't access the state what is the best strategy to deal with it? The answer is to use element attributes to pass state into the `sync$()` function.
22+
Because `sync$()` can't access the state, what is the best strategy to deal with it? The answer is to use element attributes to pass state into the `sync$()` function.
2323
> **NOTE:** If you only need to prevent the default behavior, you can simply use the standard [`preventDefault:{eventName}`](/docs/core/events/#prevent-default) syntax. This is strictly for when you need to chain events together synchronously
2424
2525
## Example: `sync$()` with state
@@ -57,7 +57,7 @@ export default component$(() => {
5757
target="_blank"
5858
data-should-prevent-default={shouldPreventDefault.value}
5959
onClick$={[
60-
sync$((e: MouseEvent, target: HTMLAnchorElement) => {
60+
sync$((e, target) => {
6161
if (target.hasAttribute('data-should-prevent-default')) {
6262
e.preventDefault();
6363
}

packages/qwik/src/core/qwik.core.api.md

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -651,7 +651,7 @@ export type QRL<TYPE = unknown> = {
651651
getCaptured(): unknown[] | null;
652652
getSymbol(): string;
653653
getHash(): string;
654-
dev: QRLDev | null;
654+
dev?: QRLDev | null;
655655
} & BivariantQrlFn<QrlArgs<TYPE>, QrlReturn<TYPE>>;
656656

657657
// @public
@@ -1643,15 +1643,11 @@ export interface SVGProps<T extends Element> extends SVGAttributes, QwikAttribut
16431643
export const sync$: <T extends Function>(fn: T) => SyncQRL<T>;
16441644

16451645
// @public (undocumented)
1646-
export interface SyncQRL<TYPE extends Function> extends QRL<TYPE> {
1647-
// (undocumented)
1646+
export type SyncQRL<TYPE extends Function> = QRL<TYPE> & {
16481647
__brand__SyncQRL__: TYPE;
1649-
(...args: TYPE extends (...args: infer ARGS) => any ? ARGS : never): TYPE extends (...args: any[]) => infer RETURN ? RETURN : never;
1650-
// (undocumented)
1651-
dev: QRLDev | null;
1652-
// (undocumented)
16531648
resolved: TYPE;
1654-
}
1649+
dev?: QRLDev | null;
1650+
} & BivariantQrlFn<QrlArgs<TYPE>, QrlReturn<TYPE>>;
16551651

16561652
// @internal
16571653
export const _task: (_event: Event, element: Element) => void;

packages/qwik/src/core/shared/jsx/types/jsx-types.unit.tsx

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ import type {
1515
QwikViewTransitionEvent,
1616
QwikVisibleEvent,
1717
} from '@qwik.dev/core';
18-
import { $, component$ } from '@qwik.dev/core';
18+
import { $, component$, sync$ } from '@qwik.dev/core';
1919
import { assertType, describe, expectTypeOf, test } from 'vitest';
2020

2121
const Fn = () => <div />;
@@ -181,11 +181,11 @@ describe('types', () => {
181181
expectTypeOf(ev).not.toBeAny();
182182
assertType<PointerEvent>(ev);
183183
})}
184-
// Infer through sync$ doesn't work
185-
// onDblClick$={sync$((ev) => {
186-
// expectTypeOf(ev).not.toBeAny();
187-
// assertType<PointerEvent>(ev);
188-
// })}
184+
// Infer through sync$
185+
onDblClick$={sync$((ev) => {
186+
expectTypeOf(ev).not.toBeAny();
187+
assertType<PointerEvent>(ev);
188+
})}
189189
// Array of handlers
190190
onInput$={[
191191
$((ev) => {
@@ -195,7 +195,7 @@ describe('types', () => {
195195
null,
196196
undefined,
197197
[
198-
$(async (ev, el) => {
198+
sync$(async (ev, el) => {
199199
expectTypeOf(ev).not.toBeAny();
200200
assertType<InputEvent>(ev);
201201
expectTypeOf(el).not.toBeAny();

packages/qwik/src/core/shared/qrl/qrl.public.ts

Lines changed: 4 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -146,7 +146,7 @@ export type QRL<TYPE = unknown> = {
146146
getCaptured(): unknown[] | null;
147147
getSymbol(): string;
148148
getHash(): string;
149-
dev: QRLDev | null;
149+
dev?: QRLDev | null;
150150
} & BivariantQrlFn<QrlArgs<TYPE>, QrlReturn<TYPE>>;
151151

152152
// https://stackoverflow.com/questions/52667959/what-is-the-purpose-of-bivariancehack-in-typescript-types/52668133#52668133
@@ -265,22 +265,12 @@ export const eventQrl = <T>(qrl: QRL<T>): QRL<T> => {
265265
};
266266

267267
/** @public */
268-
export interface SyncQRL<TYPE extends Function> extends QRL<TYPE> {
268+
export type SyncQRL<TYPE extends Function> = QRL<TYPE> & {
269269
__brand__SyncQRL__: TYPE;
270270

271-
/**
272-
* Resolve the QRL of closure and invoke it.
273-
*
274-
* @param args - Closure arguments.
275-
* @returns A return value of the closure.
276-
*/
277-
(
278-
...args: TYPE extends (...args: infer ARGS) => any ? ARGS : never
279-
): TYPE extends (...args: any[]) => infer RETURN ? RETURN : never;
280-
281271
resolved: TYPE;
282-
dev: QRLDev | null;
283-
}
272+
dev?: QRLDev | null;
273+
} & BivariantQrlFn<QrlArgs<TYPE>, QrlReturn<TYPE>>;
284274

285275
/**
286276
* Extract function into a synchronously loadable QRL.

0 commit comments

Comments
 (0)